﻿#include "dataanalyzer.h"
#include "ui_dataanalyzer.h"
#include <QScreen>
#include "logcapturedialog.h"
#include <qkeysequence.h>
#include <QClipboard>
#include <QApplication>
#include <QDateTime>
#include "odmstransferdialog.h"




DataAnalyzer::DataAnalyzer(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::DataAnalyzer)
{
    ui->setupUi(this);

    mWindowTitle = this->windowTitle();

    // 初始化参数
    initCommonParameters();

    // 初始化配置选项窗口
    initOptionsDialog();

    // 主窗口设置
    initMainWindowSetting();

    // 工具栏设置
    initToolBar();

    // 初始化数字区域
    initDigitalArea();

    // 初始化控制区域
    initControlArea();

    // 初始化图形区域
    initImageArea();

    // 初始化图例区域
    initLegendArea();

    // 隐藏控件
    hideWidget();

    // 初始化UDP接口
    initUDPGroup();

    // 初始化设备处理模块
    initDeviceProcessModule();

    // 初始化协议处理模块
    initProtocolProcessModule();

    // 初始化UDP接口模块
    initUdpMsgProcessModule();

    // 初始化数据处理模块
    initDataProcessModule();

    // 初始化日志处理模块
    initLogProcessModule();

    // 初始化曲线配置处理模块
    initCurveConfigProcessModule();

}

DataAnalyzer::~DataAnalyzer()
{
    delete ui;
    delete pOptionsDialog;
    delete pOptions;
    delete pCommonParameters;
    delete pShowMode;
    delete pDataSource;
    delete pActionDigitalDisplay;
    delete pActionImageDisplay;
    delete pLabelCycleTitle;
    delete pLabelCycleNumber;
    delete pLabelTimeStamp;
    delete pToolBarSpaceSeprator1;
    delete pToolBarSpaceSeprator2;
    delete pDigitalArea_Width;
    delete pDigitalArea_Height;
    delete pLabelsWidgetArray;
    delete pPageLabelsArray;
    delete pPageAreaAttr;
    delete pCycleAttr;
    delete pCurrentPageData;
    delete pImageArea_Width;
    delete pImageArea_Height;
    delete pLegendArea_Width;
    delete pLegendArea_Height;
    delete pScale;
    delete pControlArea_Width;
    delete pControlArea_Height;
    delete pDeviceProcessModule;
    delete pProtocolProcessModule;
    delete pUdpMsgProcessModule;
    delete pDataProcessModule;
    delete pLogProcessModule;
    delete pCurveConfigProcessModule;
    delete pUdpGroup;

}



// 设置数字显示区域尺寸
void DataAnalyzer::setDigitalAreaGeometry(int width, int height)
{
    // 设置宽度
    if(NULL == pDigitalArea_Width)
    {
        pDigitalArea_Width = new int;
    }
    *pDigitalArea_Width = width;

    // 设置高度
    if(NULL == pDigitalArea_Height)
    {
        pDigitalArea_Height = new int;
    }

    *pDigitalArea_Height = (height - ui->menubar->height() - ui->toolBar->height() - VERTICAL_MINORS) * pCommonParameters->HEIGHT_PERCENT / 100;

    return;
}



// 设置图形显示区域尺寸
void DataAnalyzer::setImageAreaGeometry(int width, int height)
{
    // 设置宽度
    if(NULL == pImageArea_Width)
    {
        pImageArea_Width = new int;
    }
    *pImageArea_Width = width * pCommonParameters->DRAW_AREA_WIDTH_PERCENT / 100;

    // 设置高度
    if(NULL == pImageArea_Height)
    {
        pImageArea_Height = new int();
    }
    *pImageArea_Height = (height - ui->menubar->height() - ui->toolBar->height() - VERTICAL_MINORS) * pCommonParameters->HEIGHT_PERCENT / 100;

    return;
}


// 设置图例区域尺寸
void DataAnalyzer::setLegendAreaGeometry(int width, int height)
{
    // 设置宽度
    if(NULL == pLegendArea_Width)
    {
        pLegendArea_Width = new int;
    }
    *pLegendArea_Width = (float)width * (100 - pCommonParameters->DRAW_AREA_WIDTH_PERCENT) / 100;

    // 设置高度
    if(NULL == pLegendArea_Height)
    {
        pLegendArea_Height = new int();
    }
    *pLegendArea_Height = ((float)height - (float)ui->menubar->height() - (float)ui->toolBar->height() - VERTICAL_MINORS) * pCommonParameters->HEIGHT_PERCENT / 100;

    return;
}


// 设置控制区域尺寸
void DataAnalyzer::setControlAreaGeometry(int width, int height)
{
    // 设置宽度
    if(NULL == pControlArea_Width)
    {
        pControlArea_Width = new int;
    }
    *pControlArea_Width = width;

    // 设置高度
    if(NULL == pControlArea_Height)
    {
        pControlArea_Height = new int();
    }
    *pControlArea_Height = (height - ui->menubar->height() - ui->toolBar->height() /*- VERTICAL_MINORS*/) * (100 - pCommonParameters->HEIGHT_PERCENT) / 100;

    return;
}



// 初始化配置选项窗口
void DataAnalyzer::initOptionsDialog()
{
    pOptionsDialog = new OptionsDialog;
    pOptionsDialog->setWindowTitle(QString("配置"));
    pOptionsDialog->setWindowIcon(QIcon(QString(":/images/options.png")));

    pOptions = new struct _options;

    pOptionsDialog->getOptions(pOptions);
    return;

}


// 初始化参数
void DataAnalyzer::initCommonParameters()
{
    GetCommons config;
    pCommonParameters = new struct _commons;
    config.readConfigFile(QApplication::applicationDirPath() + QString("/") + CONFIG_PATH);
    config.getConfig(pCommonParameters);
    return;
}


// 初始化数字显示区域
void DataAnalyzer::initDigitalArea()
{
    setDigitalAreaGeometry(this->width(), this->height());

    // 初始化显示模式
    pShowMode = new int(SHOW_MODE::DIGITAL);
    pDataSource = new int(DATA_SOURCE::LOGFILE);

    // 初始化页码
    pPageAreaAttr = new _page_area_attr;
    pPageAreaAttr->currentPage = 1;
    pPageAreaAttr->maxPage = 1;


    // 初始化周期
    pCycleAttr = new _cycle_attr;
    pCycleAttr->currentCycle = 1;

    pDigitalArea = new QWidget(ui->centralwidget);
    pDigitalArea->setFixedHeight(*pDigitalArea_Height);

    pDigitalAreaLayout = new QHBoxLayout;
    pDigitalArea->setLayout(pDigitalAreaLayout);
    pDigitalAreaLayout->setSpacing(0);              // 设置控件间距为0
    pDigitalAreaLayout->setContentsMargins(4, 6, 4, 0);

    if(NULL == pLabelsWidgetArray)
    {
        pLabelsWidgetArray = new QWidget*[pCommonParameters->COLUMNS_PER_ROW << 1]{nullptr};
    }

    for(int i = 0; i < pCommonParameters->COLUMNS_PER_ROW << 1; ++i)
    {
        if (nullptr != pLabelsWidgetArray[i]) continue;
        pLabelsWidgetArray[i] = new QWidget;
        QVBoxLayout* vLayout = new QVBoxLayout;
        pLabelsWidgetArray[i]->setLayout(vLayout);
        vLayout->setSpacing(0);
        vLayout->setContentsMargins(2, 0, 2, 0);

        QLayout* layout = pLabelsWidgetArray[i]->layout();
        for (int n = 0; n < pCommonParameters->ROWS_PER_COLUMN; ++n) {
            QLabel* label = new QLabel;
            layout->addWidget(label);
        }

        if(i % 2 == 0)
        {
            pLabelsWidgetArray[i]->setStyleSheet(QString("QWidget{background:") + *pOptions->pTitleLabelBackgroundColor + QString(QString(";}")));
        }
        else
        {
            pLabelsWidgetArray[i]->setStyleSheet(QString("QWidget{background:") + *pOptions->pValueLabelBackgroundColor + QString(QString(";}")));

        }
        pDigitalAreaLayout->addWidget(pLabelsWidgetArray[i]);

    }

    if(NULL == pPageLabelsArray)
    {
        pPageLabelsArray = new QVector<QLabel*>;
    }
    return;
}


// 初始化图形显示区域
void DataAnalyzer:: initImageArea()
{
    setImageAreaGeometry(this->width(), this->height());
    pImageArea = new QWidget(ui->centralwidget);

    pImageArea->setFixedSize(*pImageArea_Width, *pImageArea_Height);

    QVBoxLayout* pImageAreaLayout = new QVBoxLayout;
//    pImageAreaLayout->setContentsMargins(0, 0, 0, 0);
    pImageAreaLayout->setSpacing(0);
    pImageArea->setLayout(pImageAreaLayout);

    initDrawArea();
    pImageAreaLayout->addWidget(pDrawArea);

    initRulerArea();
    pImageAreaLayout->addWidget(pRulerWidget);

    // 刷新布局
    pImageArea->show();

    // 隐藏
    pImageArea->hide();

    return;
}


// 初始化图例区域
void DataAnalyzer::initLegendArea()
{
    setLegendAreaGeometry(this->width(), this->height());
    pLegendArea = new QWidget(ui->centralwidget);

    pLegendArea->setFixedSize(*pLegendArea_Width, *pLegendArea_Height);

    pLegendArea->move(*pImageArea_Width, 0);

    pLegendAreaLayout = new QHBoxLayout;
    pLegendArea->setLayout(pLegendAreaLayout);

    pLabelArea = new QWidget;
    pLegendAreaLayout->addWidget(pLabelArea);

    pLegendScrollBar = new QScrollBar;
    pLegendAreaLayout->addWidget(pLegendScrollBar);
    pLegendScrollBar->hide();

    connect(pLegendScrollBar, &QScrollBar::valueChanged, pTextBrowserDisplayValue, [=](int value){
        if(!pLabelArea)return;
        QList<QLabel*> tmplist = pLabelArea->findChildren<QLabel*>();
        if (tmplist.isEmpty()) return;
        int index = 0;
        foreach(QLabel* pLabel, tmplist)
        {
            pLabel->move(0, index * *pOptions->pLegendLabelHeight - value);
            ++index;
        }

    });
    return;

}




// 重置图形区域尺寸
void DataAnalyzer::resetImageAreaGeometry()
{
    pImageArea->setFixedSize(*pImageArea_Width, *pImageArea_Height);

    resetDrawArea();

    resetRulerArea();

    return;
}


// 重置图例区域尺寸
void DataAnalyzer::resetLegendAreaGeometry()
{
    pLegendArea->setFixedSize(*pLegendArea_Width, *pLegendArea_Height);
    pLegendArea->move(*pImageArea_Width, 0);
    updateLegendArea();
    return;
}


// 重置绘图区域尺寸
void DataAnalyzer::resetDrawArea()
{
//    pDrawArea->setFixedWidth(*pImageArea_Width);
    pDrawArea->setFixedHeight(*pImageArea_Height - pCommonParameters->RULER_AREA_HEIGHT - pImageArea->layout()->contentsMargins().top() - pImageArea->layout()->contentsMargins().bottom());

    // 解决先放大窗口再切换到绘图界面时pImageArea区域的布局不刷新尺寸问题
    pImageArea->adjustSize();

    pDrawWidget->setSize(pDrawArea->width(), pDrawArea->height());

    return;
}


// 标尺区域
void DataAnalyzer::resetRulerArea()
{
    pRulerWidget->setFixedHeight(pCommonParameters->RULER_AREA_HEIGHT);
//    pRulerWidget->setFixedSize(*pImageArea_Width, pCommonParameters->RULER_AREA_HEIGHT);

    return;
}


// 重置图形区域背景色
void DataAnalyzer::resetImageAreaBackgroundColor()
{
    pDrawArea->setStyleSheet(QString("QWidget{background:") + *pOptions->pImageAreaBackgroundColor + QString(QString(";}")));

    return;
}


// 重置图例区域背景色
void DataAnalyzer::resetLegendAreaBackgroundColor()
{
    pLegendArea->setStyleSheet(QString("QWidget{background:") + *pOptions->pLegendAreaBackgroundColor + QString(QString(";}")));

    return;
}


// 在图里区域添加标签
void DataAnalyzer::updateLegendArea()
{
    QList<LegendLabel*> labels = pLegendArea->findChildren<LegendLabel*>();
    qDeleteAll(labels.begin(), labels.end());
//    for(auto &label : std::as_const(labels))
//    {
//        delete label;
//        label = NULL ;
//    }

    QVector<PDATA_CONTEXT>* pCurvesList = pDataProcessModule->getCurvesList();


    int index = 0;

    for (auto &item : std::as_const(*pCurvesList)) {
        LegendLabel* label = new LegendLabel(pLabelArea);
        connect(label, &LegendLabel::mouseClicked, this, [=](){
            switch(label->frameShape()){
            case QFrame::NoFrame:
            {
                label->setFrameStyle(QFrame::Panel | QFrame::Sunken );
                *item->show_flag = false;
                pDrawWidget->update();
                break;
            }
            case QFrame::Panel:
            {
                label->setFrameStyle(QFrame::NoFrame | QFrame::Sunken );
                *item->show_flag = true;
                pDrawWidget->update();
                break;
            }
            default:
                break;
            }
        });

        QPalette pe;
        pe.setColor(QPalette::WindowText, QColor(*item->red, *item->green, *item->blue));

        label->setPalette(pe);
        label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);

        QFont font(*pOptions->pFont);
        font.setBold(true);
        label->setFont(font);
        label->setFixedWidth(*pLegendArea_Width);
        label->move(0, index * *pOptions->pLegendLabelHeight);
        label->setText(LEGEND_PREFIX + *item->title);
        if(*item->show_flag == false)
        {
            label->setFrameStyle(QFrame::Panel | QFrame::Sunken );
        }
        label->show();
        ++index;
    }


    QList<QLabel*> tmplist = pLabelArea->findChildren<QLabel*>();

    if(tmplist.count() * *pOptions->pLegendLabelHeight > pLabelArea->height())
    {
        pLegendScrollBar->show();
    }
    if(tmplist.count() * *pOptions->pLegendLabelHeight <= pLabelArea->height())
    {
        pLegendScrollBar->hide();
    }

    return;

}



// 绘图区域
void DataAnalyzer::initDrawArea()
{
    pDrawArea = new QWidget;
//    pDrawArea->setFixedHeight(*pImageArea_Height - pCommonParameters->RULER_AREA_HEIGHT);
    pDrawArea->setStyleSheet(QString("QWidget{background:") + *pOptions->pImageAreaBackgroundColor + QString(QString("; border-radius: 4px}")));

    // 创建绘图控件
    pDrawWidget = new MainDrawWidget(pDrawArea);
//    pDrawWidget->setSize(pDrawArea->width(), pDrawArea->height());
    pDrawWidget->setCurrentCycle(pCycleAttr->currentCycle);
    pDrawWidget->setScale(*pScale);

//    pDrawWidget->setAttribute(Qt::WA_StyledBackground,true);

    return;
}

// 标尺区域
void DataAnalyzer::initRulerArea()
{
    pRulerWidget = new RulerWidget;
    pRulerWidget->setFixedHeight(pCommonParameters->RULER_AREA_HEIGHT);
    pRulerWidget->setScale(*pScale);
    pRulerWidget->setCommonParameters(pCommonParameters);

    return;
}


// 初始化控制区域
void DataAnalyzer::initControlArea()
{
    setControlAreaGeometry(this->width(), this->height());

    pControlArea = new QWidget(ui->centralwidget);

    pControlArea->setFixedSize(this->width(), *pControlArea_Height);
    pControlArea->move(0,pDigitalArea->height());

    pControlAreaLayout = new QHBoxLayout;
    pControlArea->setLayout(pControlAreaLayout);
    pControlAreaLayout->setSpacing(5);
    pControlAreaLayout->setContentsMargins(5, 0, 0, 15);


    initDisplayValueArea();

    initCurveModifyArea();

    initZoomArea();

    initCycleArea();

    initPageAndLogoArea();

    return;
}


// 初始化TextBrowser控件
void DataAnalyzer::initDisplayValueArea()
{
    pWidgetDisplayValue = new MyTextBrowser;
    pWidgetDisplayValue->installEventFilter(this);
//    pWidgetDisplayValue = new QWidget;
    pWidgetDisplayValue->setMaximumWidth(this->width() / CONTROL_AREA_EQUAL_PARTS);
    QHBoxLayout* pLayout = new QHBoxLayout;
    pLayout->setContentsMargins(0, 0, 0, 0);  // 设置控件距离边界值
    pLayout->setSpacing(1);             // 设置控件间距为0
    pWidgetDisplayValue->setLayout(pLayout);
    pTextBrowserDisplayValue = new QFrame;
    pTextBrowserDisplayValue->setStyleSheet(QString("background:#FFFFFF; /*border: 1px solid white; */border-radius: 4px"));
    pTextBrowserDisplayValue->setContentsMargins(0, 0, 0, 0);
    pLayout->addWidget(pTextBrowserDisplayValue);
    pControlAreaLayout->addWidget(pWidgetDisplayValue);

    pTextScrollBar = new QScrollBar;
    pLayout->addWidget(pTextScrollBar);
    pTextScrollBar->hide();

    connect(pTextScrollBar, &QScrollBar::valueChanged, pTextBrowserDisplayValue, [=](int value){
        QVector<PDATA_CONTEXT>* pCurvesList = pDataProcessModule->getCurvesList();

        if(pCurvesList)
        {
            QList<MyWidget*> pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
            int index = 0;
            foreach(MyWidget* pWidget, pWidgetList)
            {
                pWidget->move(0, index * TEXTBROWSER_LABEL_HEIGHT - value);
                ++index;
            }
        }
    });

    connect(pWidgetDisplayValue, &MyTextBrowser::copyed, this, [&](){
        if (DATA_SOURCE::UDP == *pDataSource && !pauseFlag) return;
        QVector<PDATA_CONTEXT> curvesList = *pDataProcessModule->getCurvesList();
        if (curvesList.isEmpty()) return;
        QString text;
        text.append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz:") + "\n");
        int cycle = pCycleAttr->currentCycle;
        for (auto &item : std::as_const(curvesList)) {
            text.append(*item->title + " : " + *item->allCyclesStrValues->at(cycle - 1) + "\n");
        }
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(text);

    });

    return;

}



// 初始化曲线增删改区域
void DataAnalyzer::initCurveModifyArea()
{
    pWidgetCurveModify = new QWidget;
    pWidgetCurveModify->setMaximumWidth(this->width() / CONTROL_AREA_EQUAL_PARTS);
    QHBoxLayout* pLayout = new QHBoxLayout;
    pWidgetCurveModify->setLayout(pLayout);
    pLayout->setContentsMargins(0, 0, 0, 0);
    pControlAreaLayout->addWidget(pWidgetCurveModify);

    pGroupBoxCurveSelection = new QGroupBox;                                                               // 变量选择组控件
//    pGroupBoxCurveSelection->hide();
    pLayout->addWidget(pGroupBoxCurveSelection);
    pGroupBoxCurveSelection->setTitle(QString("曲线增删改"));

    QVBoxLayout* pGroupBoxLayout = new QVBoxLayout;
    pGroupBoxLayout->setContentsMargins(5, 0, 5, 0);
    pGroupBoxCurveSelection->setLayout(pGroupBoxLayout);

    QWidget* pAddArea = new QWidget;
    QWidget* pDelArea = new QWidget;
    pGroupBoxLayout->addWidget(pAddArea);
    pGroupBoxLayout->addWidget(pDelArea);

    QHBoxLayout* pAddAreaLayout = new QHBoxLayout;
    pAddAreaLayout->setContentsMargins(0, 0, 0, 0);
    pAddAreaLayout->setSpacing(1);
    pAddArea->setLayout(pAddAreaLayout);
    pComboBoxCurveAdd = new QComboBox;
    pButtonCurveAdd = new QPushButton;
    pButtonCurveAdd->setMaximumWidth(BUTTON_MAX_WIDTH);
    pButtonCurveAdd->setIcon(QIcon(QString(":/images/add.png")));
    connect(pButtonCurveAdd, &QPushButton::clicked, this, &DataAnalyzer::curveAddButtonSlot, Qt::UniqueConnection);


    pAddAreaLayout->addWidget(pComboBoxCurveAdd);
    pAddAreaLayout->addWidget(pButtonCurveAdd);

    QHBoxLayout* pDelAreaLayout = new QHBoxLayout;
    pDelAreaLayout->setContentsMargins(0, 0, 0, 0);
    pDelAreaLayout->setSpacing(1);
    pDelArea->setLayout(pDelAreaLayout);
    pComboBoxCurveDel = new QComboBox;
    pButtonCurveDel = new QPushButton;
    pButtonCurveChangeColor = new QPushButton;
    pButtonCurveDel->setMaximumWidth(BUTTON_MAX_WIDTH);
    pButtonCurveDel->setIcon(QIcon(QString(":/images/del.png")));
    pButtonCurveChangeColor->setMaximumWidth(BUTTON_MAX_WIDTH);
    pButtonCurveChangeColor->setIcon(QIcon(QString(":/images/palette.png")));

    connect(pButtonCurveDel, &QPushButton::clicked, this, &DataAnalyzer::curveDelButtonSlot, Qt::UniqueConnection);

    connect(pComboBoxCurveDel, &QComboBox::currentTextChanged, this, &DataAnalyzer::curveDelComboBoxIndexChangedSlot, Qt::UniqueConnection);

    connect(pButtonCurveChangeColor, &QPushButton::clicked, this, &DataAnalyzer::curveChangeColorButtonSlot, Qt::UniqueConnection);

    pDelAreaLayout->addWidget(pComboBoxCurveDel);
    pDelAreaLayout->addWidget(pButtonCurveDel);
    pDelAreaLayout->addWidget(pButtonCurveChangeColor);

    return;
}

void DataAnalyzer::initZoomArea()
{
    pWidgetZoomArea = new QWidget;
    pWidgetZoomArea->setMaximumWidth(this->width() / CONTROL_AREA_EQUAL_PARTS);
    pControlAreaLayout->addWidget(pWidgetZoomArea);
    pWidgetZoomAreaLayout = new QVBoxLayout;
    pWidgetZoomAreaLayout->setContentsMargins(5, 0, 5, 0);
    pWidgetZoomArea->setLayout(pWidgetZoomAreaLayout);

    initXZoomArea();
    initYZoomArea();

    return;
}


// 初始化横坐标缩放组控件
void DataAnalyzer::initXZoomArea()
{
    pGroupBoxXZoom = new QGroupBox;
//    pGroupBoxXZoom->hide();
    pGroupBoxXZoom->setTitle(QString("横坐标(X轴)缩放"));
    pWidgetZoomAreaLayout->addWidget(pGroupBoxXZoom);

    QHBoxLayout* pLayout = new QHBoxLayout;
    pLayout->setContentsMargins(5, 0, 5, 0);
    pLayout->setSpacing(1);
    pGroupBoxXZoom->setLayout(pLayout);

    pComboBoxXZoom = new QComboBox;
    pButtonXZoomIn = new QPushButton;
    pButtonXZoomOut = new QPushButton;
    pButtonXZoomIn->setMaximumWidth(BUTTON_MAX_WIDTH);
    pButtonXZoomIn->setIcon(QIcon(QString(":/images/zoom_in.png")));
    pButtonXZoomOut->setMaximumWidth(BUTTON_MAX_WIDTH);
    pButtonXZoomOut->setIcon(QIcon(QString(":/images/zoom_out.png")));
//    pComboBoxXZoom->setStyleSheet("QComboBox{text:#FFFFFF}");

    pLayout->addWidget(pComboBoxXZoom);
    pLayout->addWidget(pButtonXZoomIn);
    pLayout->addWidget(pButtonXZoomOut);

    // 缩放下拉框添加项目
    pComboBoxXZoom->clear();
    pComboBoxXZoom->addItem(QString::number(1 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");
    pComboBoxXZoom->addItem(QString::number(2 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");
    pComboBoxXZoom->addItem(QString::number(5 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");
    pComboBoxXZoom->addItem(QString::number(10 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");
    pComboBoxXZoom->addItem(QString::number(20 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");
    pComboBoxXZoom->addItem(QString::number(50 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");
    pComboBoxXZoom->addItem(QString::number(100 * (MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS) * pCommonParameters->SYSTEM_CYCLE, 'f', 1) + " 秒/大格");


    pComboBoxXZoom->setCurrentIndex(pComboBoxXZoom->count() - 1);
    pScale = new int(20);

    connect(pComboBoxXZoom, &QComboBox::currentTextChanged, this, &DataAnalyzer::curveXRangeChangedSlot, Qt::UniqueConnection);
    connect(pButtonXZoomIn, &QPushButton::clicked, this, &DataAnalyzer::zoominButtonSlot, Qt::UniqueConnection);
    connect(pButtonXZoomOut, &QPushButton::clicked, this, &DataAnalyzer::zoomoutButtonSlot, Qt::UniqueConnection);

    return;
}


// 初始化纵坐标缩放组控件
void DataAnalyzer::initYZoomArea()
{
    pGroupBoxYZoom = new QGroupBox;
//    pGroupBoxYZoom->hide();
    pGroupBoxYZoom->setTitle(QString("纵坐标(Y轴)缩放和平移"));
    pWidgetZoomAreaLayout->addWidget(pGroupBoxYZoom);

    QHBoxLayout* pLayout = new QHBoxLayout;
    pLayout->setContentsMargins(5, 0, 5, 0);
    pLayout->setSpacing(1);
    pGroupBoxYZoom->setLayout(pLayout);

    QLabel* pLabelMin = new QLabel;
    pLabelMin->setMaximumWidth(LABEL_MAX_WIDTH);
    pLabelMin->setText("最小值");

    pLineEditMin = new QLineEdit;
    pLineEditMin->setStyleSheet("background: transparent; color: #15855B; font: bold; border: 1px solid white; border-radius: 2px");

    QLabel* pLabelMax = new QLabel;
    pLabelMax->setMaximumWidth(LABEL_MAX_WIDTH);
    pLabelMax->setText("最大值");

    pLineEditMax = new QLineEdit;
    pLineEditMax->setStyleSheet("background: transparent; color: #174BBD; font: bold; border: 1px solid white;border-radius: 2px");

    pButtonConfirm = new QPushButton;
    pButtonConfirm->setMaximumWidth(BUTTON_MAX_WIDTH);
    pButtonConfirm->setIcon(QIcon(QString(":/images/complete.png")));

    connect(pButtonConfirm, &QPushButton::clicked, this, &DataAnalyzer::rangeChangeButtonSlot, Qt::UniqueConnection);

    pLayout->addWidget(pLabelMin);
    pLayout->addWidget(pLineEditMin);
    pLayout->addWidget(pLabelMax);
    pLayout->addWidget(pLineEditMax);
    pLayout->addWidget(pButtonConfirm);

    return;

}


// 初始化周期播放组控件
void DataAnalyzer::initCycleArea()
{
    pWidgetCycle = new QWidget;
    pWidgetCycle->setMaximumWidth(this->width() / CONTROL_AREA_EQUAL_PARTS);
    QHBoxLayout* pLayout = new QHBoxLayout;
    pWidgetCycle->setLayout(pLayout);
    pLayout->setContentsMargins(5, 0, 5, 0);
    pControlAreaLayout->addWidget(pWidgetCycle);

    pGroupBoxCycle = new QGroupBox;
//    pGroupBoxCycle->hide();
    pGroupBoxCycle->setTitle(QString("周期播放"));

    QVBoxLayout* pGroupBoxLayout = new QVBoxLayout;
    pGroupBoxLayout->setContentsMargins(5, 0, 5, 0);
    pGroupBoxLayout->setSpacing(1);
    pGroupBoxCycle->setLayout(pGroupBoxLayout);
    pLayout->addWidget(pGroupBoxCycle);

    QWidget* pWidgetButton = new QWidget;
    QWidget* pWidgetSlider = new QWidget;


    pGroupBoxLayout->addWidget(pWidgetButton);
    pGroupBoxLayout->addWidget(pWidgetSlider);

    QHBoxLayout* pWidgetButtonLayout = new QHBoxLayout;
    pWidgetButton->setLayout(pWidgetButtonLayout);
//    pWidgetButtonLayout->setContentsMargins(0, 0, 0, 0);
    pWidgetButtonLayout->setSpacing(1);

    pButtonMultipleBackard = new QPushButton;
    pButtonBackward = new QPushButton;
    pButtonForward = new QPushButton;
    pButtonMultipleForward = new QPushButton;

//    // 设置快捷键
//    QKeySequence keyBackward(Qt::Key_Left);
//    QKeySequence keyMultipleBackward(Qt::Key_Left | Qt::Key_Shift);
//    QKeySequence keyForward(Qt::Key_Right);
//    QKeySequence keyMultipleForward(QKeySequence(QLatin1String("Shift+Right")));
//    pButtonBackward->setShortcut(keyBackward);
//    pButtonMultipleBackard->setShortcut(keyMultipleForward);
//    pButtonForward->setShortcut(keyForward);
//    pButtonMultipleForward->setShortcut(keyMultipleBackward);

    pButtonMultipleBackard->setIcon(QIcon(QString(":/images/fast_backward.png")));
    pButtonBackward->setIcon(QIcon(QString(":/images/backward.png")));
    pButtonForward->setIcon(QIcon(QString(":/images/forward.png")));
    pButtonMultipleForward->setIcon(QIcon(QString(":/images/fast_forward.png")));
    pButtonMultipleBackard->setDisabled(true);
    pButtonBackward->setDisabled(true);

    pWidgetButtonLayout->addWidget(pButtonMultipleBackard);
    pWidgetButtonLayout->addWidget(pButtonBackward);
    pWidgetButtonLayout->addWidget(pButtonForward);
    pWidgetButtonLayout->addWidget(pButtonMultipleForward);

    connect(pButtonMultipleBackard, &QPushButton::clicked, this, &DataAnalyzer::multipleBackwardButtonSlot, Qt::UniqueConnection);
    connect(pButtonBackward, &QPushButton::clicked, this, &DataAnalyzer::backwardButtonSlot, Qt::UniqueConnection);
    connect(pButtonForward, &QPushButton::clicked, this, &DataAnalyzer::forwardButtonSlot, Qt::UniqueConnection);
    connect(pButtonMultipleForward, &QPushButton::clicked, this, &DataAnalyzer::multipleForwardButtonSlot, Qt::UniqueConnection);


    QHBoxLayout* pWidgetSliderLayout = new QHBoxLayout;
//    pWidgetSliderLayout->setContentsMargins(0, 0, 0, 0);
    pWidgetSlider->setLayout(pWidgetSliderLayout);

    pCycleSlider = new QSlider(Qt::Horizontal);
    pWidgetSliderLayout->addWidget(pCycleSlider);
    pCycleSlider->setMinimum(1);
    pCycleSlider->setTabletTracking(true);
    pCycleSlider->releaseKeyboard();

    connect(pCycleSlider, &QSlider::valueChanged, this, &DataAnalyzer::cycleSliderSlot, Qt::UniqueConnection);

    return;
}


// 初始化翻页和Logo区域
void DataAnalyzer::initPageAndLogoArea()
{
    pWidgetPageAndLogo = new QWidget;
    pWidgetPageAndLogo->setMaximumWidth(this->width() / CONTROL_AREA_EQUAL_PARTS);
    pPageAndLogoLayout = new QVBoxLayout;
    pPageAndLogoLayout->setContentsMargins(0, 0, 0, 0);
    pWidgetPageAndLogo->setLayout(pPageAndLogoLayout);
    pControlAreaLayout->addWidget(pWidgetPageAndLogo);
    initPageArea();
    initLogoArea();

    return;
}



// 初始化翻页组控件
void DataAnalyzer::initPageArea()
{    
    pGroupBoxPage = new QGroupBox;
    pGroupBoxPage->setTitle(QString("翻页区域"));

    QHBoxLayout* pGroupBoxPageLayout = new QHBoxLayout;
    pGroupBoxPageLayout->setContentsMargins(5, 0, 5, 0);
    pGroupBoxPage->setLayout(pGroupBoxPageLayout);
    pButtonHomePage = new QPushButton;
    pButtonPageUp = new QPushButton;
    pLineEnditPage = new QLineEdit;
    pButtonPageDown = new QPushButton;
    pButtonEndPage = new QPushButton;

    pLineEnditPage->setStyleSheet("border: 1px solid white; border-radius: 4px");

    // 设置翻页按钮快捷键
    QKeySequence keyHomePage(Qt::Key_Home);
    QKeySequence keyPageUp(Qt::Key_Up);
    QKeySequence keyPageDown(Qt::Key_Down);
    QKeySequence keyEndPage(Qt::Key_End);
    pButtonHomePage->setShortcut(keyHomePage);
    pButtonPageUp->setShortcut(keyPageUp);
    pButtonPageDown->setShortcut(keyPageDown);
    pButtonEndPage->setShortcut(keyEndPage);

    pButtonHomePage->setText(HOME_PAGE);
    pButtonPageUp->setText(PAGE_UP);
    pLineEnditPage->setMaximumWidth(LINEEDIT_MAX_WIDTH);
    pLineEnditPage->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
    pLineEnditPage->setText(QString::number(pPageAreaAttr->currentPage));
    pButtonPageDown->setText(PAGE_DOWN);
    pButtonEndPage->setText(END_PAGE);

    pButtonHomePage->setDisabled(true);
    pButtonPageUp->setDisabled(true);

    pGroupBoxPageLayout->addWidget(pButtonHomePage);
    pGroupBoxPageLayout->addWidget(pButtonPageUp);
    pGroupBoxPageLayout->addWidget(pLineEnditPage);
    pGroupBoxPageLayout->addWidget(pButtonPageDown);
    pGroupBoxPageLayout->addWidget(pButtonEndPage);

    connect(pButtonHomePage, &QPushButton::clicked, this, &DataAnalyzer::homepageButtonSlot, Qt::UniqueConnection);
    connect(pButtonPageUp, &QPushButton::clicked, this, &DataAnalyzer::pageupButtonSlot, Qt::UniqueConnection);
    connect(pLineEnditPage, &QLineEdit::returnPressed, this, &DataAnalyzer::lineeditEnterSlot, Qt::UniqueConnection);
    connect(pButtonPageDown, &QPushButton::clicked, this, &DataAnalyzer::pagedownButtonSlot, Qt::UniqueConnection);
    connect(pButtonEndPage, &QPushButton::clicked, this, &DataAnalyzer::endpageButtonSlot, Qt::UniqueConnection);

    return;
}


// 初始化Logo标签
void DataAnalyzer::initLogoArea()
{
    QWidget* widget = new QWidget;
    QHBoxLayout* layout = new QHBoxLayout(widget);
    layout->setContentsMargins(0, 0, 0, 0);
    QLabel* pLabelLogo = new QLabel;
    layout->addWidget(pLabelLogo);
    pLabelLogo->setScaledContents(true);
    pLabelLogo->setFixedSize(199, 64);
    pLabelLogo->setPixmap(QPixmap(":/images/copyright.png"));
    pLabelLogo->setAlignment(Qt::AlignCenter | Qt::AlignBottom);
    pPageAndLogoLayout->addWidget(pGroupBoxPage);
    pPageAndLogoLayout->addWidget(widget);

    return;
}



// 窗口缩放
void DataAnalyzer::resizeWindowGeometry(int width, int height)
{
    // 重置工具栏
    resetToolBarGeometry(width);

    // 数字显示区域缩放
    setDigitalAreaGeometry(width, height);
    resizeDigitalAreaGeometry(width, height);
    resizeLabelsGeometry();

    // 图形显示区域缩放
    setImageAreaGeometry(width, height);
    resetImageAreaGeometry();

    // 图例区域缩放
    setLegendAreaGeometry(width, height);
    resetLegendAreaGeometry();

    // 控制区域缩放
    setControlAreaGeometry(width, height);
    resizeControlAreaGeometry(width, height);

    if(nullptr == pDigitalArea || nullptr == pLabelArea || nullptr == pPageLabelsArray || 0 == pPageLabelsArray->length()) return;

    if(*pDataSource == DATA_SOURCE::LOGFILE || pauseFlag)
    {
        updateFromLogOrPauseData();
        createPageLabel();
        updateCurrentPageSlot();
    }

    return;
}


// 重置窗口背景色
void DataAnalyzer::resetWinddowBackgroundColor()
{
    // 设置背景色
    ui->centralwidget->setStyleSheet(QString("QWidget{background:") + QString(*pOptions->pWindowBackgroundColor) + QString(";}"));

    return;
}


// 重置工具栏背景色
void DataAnalyzer::resetToolbarBackgroundColor()
{
    // 设置背景色
    ui->toolBar->setStyleSheet(QString("QToolBar{") +\
                "background-color:" + QString(*pOptions->pToolbarBackgroundColor) + ";"\
                "border: none;" +\
                "padding: 1px" +\
                "}");

    return;
}


// 重置图形区域背景色
void resetImageAreaBackgroundColor()
{

}


// 重置数字显示区域尺寸
void DataAnalyzer::resizeDigitalAreaGeometry(int width, int height)
{
    if(NULL == pDigitalArea) return;

    pDigitalArea->setFixedSize(width, (height - ui->menubar->height() - ui->toolBar->height() - 15) * pCommonParameters->HEIGHT_PERCENT / 100);

    return;

}


// 重置控制区域尺寸
void DataAnalyzer::resizeControlAreaGeometry(int width, int height)
{
    if(NULL == pControlArea) return;

    pControlArea->setFixedSize(width, (height - ui->menubar->height() - ui->toolBar->height() - 15) * (100 - pCommonParameters->HEIGHT_PERCENT) / 100);
    pControlArea->move(0,pDigitalArea->height());

    pWidgetDisplayValue->setMaximumWidth(width / CONTROL_AREA_EQUAL_PARTS);

    pWidgetCurveModify->setMaximumWidth(width / CONTROL_AREA_EQUAL_PARTS);

    pWidgetZoomArea->setMaximumWidth(width / CONTROL_AREA_EQUAL_PARTS);

    pWidgetCycle->setMaximumWidth(width / CONTROL_AREA_EQUAL_PARTS);

    pWidgetPageAndLogo->setMaximumWidth(width / CONTROL_AREA_EQUAL_PARTS);

    updateTextbrowser();

    return;

}


// 重置标签尺寸
void DataAnalyzer::resizeLabelsGeometry()
{
//    clearLabelsArray();
//    showCurrentPage();

    return;
}




// 重置数字显示区域标签字体
void DataAnalyzer::resetLabelFont()
{
    for(int n = 0; n < pPageLabelsArray->count(); ++n)
    {
        (*pPageLabelsArray)[n]->setFont(*pOptions->pFont);
    }

    return;
}



// 重置数字显示区域标签颜色
void DataAnalyzer::resetLabelColor()
{
    QPalette pe;
    pe.setColor(QPalette::WindowText, QColor(*pOptions->pLabelTextColor));

    for(int n = 0; n < pPageLabelsArray->count(); ++n)
    {
        // 设置标签前景色
        (*pPageLabelsArray)[n]->setPalette(pe);
    }

    for(int n = 0; n < pCommonParameters->COLUMNS_PER_ROW << 1; ++n)
    {
        if(n % 2 == 0)
        {
            pLabelsWidgetArray[n]->setStyleSheet(QString(QString("QWidget{background:")) + *pOptions->pTitleLabelBackgroundColor + QString(QString(";}")));
        }
        else
        {
            pLabelsWidgetArray[n]->setStyleSheet(QString(QString("QWidget{background:")) + *pOptions->pValueLabelBackgroundColor + QString(QString(";}")));
        }
    }

    return;
}



// 初始化标签
void DataAnalyzer::clearLabelsArray()
{
    if (!pPageLabelsArray) return;

    if(pPageLabelsArray->count() > 0)
    {
        for(int n = 0; n < pCommonParameters->COLUMNS_PER_ROW << 1; ++n)
        {
            QList<QLabel*> labels = pLabelsWidgetArray[n]->findChildren<QLabel*>();
            foreach(QLabel* label, labels)
            {
                label->clear();
            }
        }
    }
    pPageLabelsArray->clear();

    return;
}



// 窗口尺寸变化事件响应
void DataAnalyzer::resizeEvent(QResizeEvent* size)
{
    resizeWindowGeometry(size->size().width(), size->size().height());

    return;
}


// 鼠标滚轮事件
void DataAnalyzer::wheelEvent(QWheelEvent *event)
{
    if (!pCycleAttr) return;
    if (!pButtonForward) return;
    if (!pButtonMultipleForward) return;
    if (!pButtonBackward) return;
    if (!pButtonMultipleBackard) return;
    if (!pDataSource) return;
    if (!pCycleSlider) return;

    QPoint angles = event->angleDelta() / 8;

    if (DATA_SOURCE::LOGFILE == *pDataSource || pauseFlag) {
        int step = *pScale * 4;
        if(angles.x() > 0) {
            cycleChange(step);

        }
        if (angles.x() < 0) {
            cycleChange(-step);

        }
    }


    if(angles.y() > 0) {                    // 当滚轮远离使用者时（上滚）
        // 数值界面滚动鼠标滚轮时为上翻页功能
        if (pImageArea->isHidden()) {
            pageupButtonSlot();

            return;
        }

        // 放大图形
        if (*pScale < 100) *pScale -= 10;
        if (*pScale >= 100) *pScale -= 100;

        if (*pScale < 0) *pScale = 1;
        if(*pScale < 100)
        {
            if(pComboBoxXZoom->currentText().isEmpty()) {
                pComboBoxXZoom->setCurrentIndex(pComboBoxXZoom->count() - 1);
            } else if(pComboBoxXZoom->currentIndex() - 1 >= 0) {
                pComboBoxXZoom->setCurrentIndex(pComboBoxXZoom->currentIndex() - 1);
            }

        } else {
            pRulerWidget->setScale(*pScale);
            pDrawWidget->setScale(*pScale);
            pDrawWidget->update();
        }

    }
    if(angles.y() < 0) {                                     // 当滚轮向使用者方向旋转时（下滚）
        // 数值界面滚动鼠标滚轮时为下翻页功能
        if (pImageArea->isHidden()) {
            pagedownButtonSlot();

            return;
        }

        // 缩小图形
        if (*pScale < 100) *pScale += 10;
        if (*pScale >= 100) *pScale += 100;
        if(pComboBoxXZoom->currentIndex() < pComboBoxXZoom->count() - 1)
        {

            if (pComboBoxXZoom->currentIndex() + 1 <= pComboBoxXZoom->count()) {
                pComboBoxXZoom->setCurrentIndex(pComboBoxXZoom->currentIndex() + 1);
            }

        } else {
            pComboBoxXZoom->setEditable(true);
            pComboBoxXZoom->setCurrentText("");
            pRulerWidget->setScale(*pScale);
            pDrawWidget->setScale(*pScale);
            pDrawWidget->update();
        }


    }
    return;

}


// 主窗口设置
void DataAnalyzer::initMainWindowSetting()
{
    // 设置背景色（渐变色）
    QString style = "QWidget#centralwidget{background-color:qlineargradient(x1 : 0, y1 : 0, x2 : 1, y2 : 1,\
            stop: 0 #57575B,\
            stop: 0.33 #85858A,\
            stop: 0.66 #B6B6BB,\
            stop: 1" + QString(*pOptions->pWindowBackgroundColor) + ")}";
    ui->centralwidget->setStyleSheet(style);

//    ui->centralwidget->setStyleSheet(QString("QWidget{background:") + QString(*pOptions->pWindowBackgroundColor) + QString(";}"));

    this->setWindowTitle(QApplication::applicationName() + "_" + ABOUT_TEXT_VERSION + "(" + ABOUT_BIT_VERSION + ")");
    mWindowTitle = this->windowTitle();

    // 设置窗口默认大小
    this->resize(pCommonParameters->DEFAULT_WIDTH, pCommonParameters->DEFAULT_HEIGHT);

    // 屏幕居中
    QRect tScreenRect = this->screen()->availableGeometry();

    if (tScreenRect.height() - height() <= 0) this->move((tScreenRect.width() - width()) >> 1, 0);
    else this->move((tScreenRect.width() - width()) >> 1, (tScreenRect.height() - height()) >> 1);

    // 添加关于菜单
    connect(ui->menubar->addAction(QString("关于")), &QAction::triggered, this,  [=](){
        QMessageBox::about(this, QString("关于") + QApplication::applicationName() + "_" + ABOUT_TEXT_VERSION, ABOUT_TEXT);
    });

    ui->actionOpenConfig->setDisabled(true);
    ui->actionSaveConfig->setDisabled(true);
    ui->actionLogCapture->setDisabled(true);

    return;
}


// 工具栏设置
void DataAnalyzer::initToolBar()
{
    // 设置背景色
    ui->toolBar->setStyleSheet(QString("QToolBar{background-color:") + QString(*pOptions->pToolbarBackgroundColor) + QString(";\
                border: none;\
                padding: 1px\
                }"));

    // 菜单栏和工具栏按钮绑定槽函数

    // 设备选择按钮
    connect(ui->actionDeviceSelect,&QAction::triggered, this, &DataAnalyzer::actionDeviceSelectSlot, Qt::UniqueConnection);

    // 配置选项按钮
    connect(ui->actionOptions,&QAction::triggered, this, &DataAnalyzer::actionOptionsSlot, Qt::UniqueConnection);

    // 退出按钮
    connect(ui->actionQuit, &QAction::triggered, this, &DataAnalyzer::actionQuitSlot, Qt::UniqueConnection);

    // 获取数据按钮
    connect(ui->actionReceiveMessage, &QAction::triggered, this, &DataAnalyzer::actionReceiveMessageSlot, Qt::UniqueConnection);
    ui->actionReceiveMessage->setDisabled(true);

    // 暂停按钮
    connect(ui->actionPause, &QAction::triggered, this, &DataAnalyzer::actionPauseSlot, Qt::UniqueConnection);
    ui->actionPause->setDisabled(true);

    // 停止并保存按钮
    connect(ui->actionStopAndSave, &QAction::triggered, this, &DataAnalyzer::actionStopAndSaveSlot, Qt::UniqueConnection);
    ui->actionStopAndSave->setDisabled(true);

    // 打开日志按钮
    connect(ui->actionOpenLog, &QAction::triggered, this, &DataAnalyzer::actionOpenLogSlot, Qt::UniqueConnection);
    ui->actionOpenLog->setDisabled(true);

    // 停止播放按钮
    connect(ui->actionStopPlay, &QAction::triggered, this, &DataAnalyzer::actionStopPlaySlot, Qt::UniqueConnection);
    ui->actionStopPlay->setDisabled(true);

    // 重放按钮
    connect(ui->actionReplay, &QAction::triggered, this, &DataAnalyzer::actionReplaySlot, Qt::UniqueConnection);
    ui->actionReplay->setDisabled(true);

    // 工具栏新增数字显示切换按钮
    pActionDigitalDisplay = new QAction;
    pActionDigitalDisplay = ui->toolBar->addAction(QIcon(":/images/digital.png"),QString("数字显示"));
    pActionDigitalDisplay->setDisabled(true);

    // 数字显示切换按钮连接到对应的数显槽函数
    connect(pActionDigitalDisplay, &QAction::triggered, this, &DataAnalyzer::actionDigitalDisplaySlot, Qt::UniqueConnection);

    // 工具栏新增图形显示切换按钮
    pActionImageDisplay = new QAction;
    pActionImageDisplay = ui->toolBar->addAction(QIcon(QString(":/images/analog.png")), QString("模拟显示"));
    pActionImageDisplay->setDisabled(true);

    // 图形显示切换按钮连接到对应的模拟显示槽函数
    connect(pActionImageDisplay, &QAction::triggered, this, &DataAnalyzer::actionImageDisplaySlot, Qt::UniqueConnection);

    connect(ui->actionOpenConfig, &QAction::triggered, this, &DataAnalyzer::actionImportConfigSlog, Qt::UniqueConnection);

    connect(ui->actionSaveConfig, &QAction::triggered, this, &DataAnalyzer::actionExportConfigSlot, Qt::UniqueConnection);

    connect(ui->actionLogCapture, &QAction::triggered, this, &DataAnalyzer::actionLogCapture, Qt::UniqueConnection);

    connect(ui->actionBatchReceive, &QAction::triggered, this, &DataAnalyzer::actionBatchReceiveSlot, Qt::UniqueConnection);

    mODMSLogLastPath = QCoreApplication::applicationDirPath();      // 设置ODMS日志初始路径
    connect(ui->actionODMS, &QAction::triggered, this, &DataAnalyzer::actionODMSTransfer, Qt::UniqueConnection);

    ui->actionBatchReceive->setDisabled(true);

    connect(ui->actionStopBatchReceive, &QAction::triggered, this, &DataAnalyzer::actionStopBatchSlot, Qt::UniqueConnection);
    ui->actionStopBatchReceive->setDisabled(true);

    // 工具栏插入分隔符
    QAction* action_Separator1 = ui->toolBar->addSeparator();
    action_Separator1->setVisible(false);

    // 插入分隔的空白标签
    pToolBarSpaceSeprator1 = new QLabel;
    ui->toolBar->addWidget(pToolBarSpaceSeprator1);

    // 工具栏插入周期标题显示标签
    pLabelCycleTitle = new QLabel;
    pLabelCycleTitle->setFixedWidth(CYCLE_TITLE_WIDTH);
    ui->toolBar->addWidget(pLabelCycleTitle);
    pLabelCycleTitle->setStyleSheet(QString("QLabel{color: black}"));

    // 工具栏插入周期号标签
    pLabelCycleNumber = new QLabel;
    pLabelCycleNumber->setFixedWidth(CYCLE_WIDTH);
    pLabelCycleNumber->setAlignment(Qt::AlignCenter);
    ui->toolBar->addWidget(pLabelCycleNumber);
    pLabelCycleNumber->setStyleSheet(QString("QLabel{color: black}"));

    // 工具栏插入分隔空白标签
    pToolBarSpaceSeprator2 = new QLabel;
    ui->toolBar->addWidget(pToolBarSpaceSeprator2);

    // 工具栏插入时间显示标签
    pLabelTimeStamp = new QLabel;
    pLabelTimeStamp->setFixedWidth(TIME_STAMP_WIDTH);
    ui->toolBar->addWidget(pLabelTimeStamp);
    pLabelTimeStamp->setStyleSheet(QString("QLabel{color: black}"));

    return;
}


// 重置工具栏尺寸
void DataAnalyzer::resetToolBarGeometry(int width)
{
    quint16 tWidth = 0;                                     // 剩余的工具栏宽度
    tWidth = width                                          // 计算剩余工具栏宽度，当前窗口宽度 - 标签的x坐标
            - ui->toolBar->actionGeometry(ui->actionDeviceSelect).width()
            - ui->toolBar->actionGeometry(ui->actionReceiveMessage).width()
            - ui->toolBar->actionGeometry(ui->actionBatchReceive).width()
            - ui->toolBar->actionGeometry(ui->actionStopBatchReceive).width()
            - ui->toolBar->actionGeometry(ui->actionStopAndSave).width()
            - ui->toolBar->actionGeometry(ui->actionOpenLog).width()
            - ui->toolBar->actionGeometry(ui->actionStopPlay).width()
            - ui->toolBar->actionGeometry(ui->actionReplay).width()
            - ui->toolBar->actionGeometry(pActionDigitalDisplay).width()
            - ui->toolBar->actionGeometry(pActionImageDisplay).width()
            ;

    quint16 tSepratorWidth = (float)SPACE_WIDTH_PERCENT * tWidth / 100;
    pToolBarSpaceSeprator1->setFixedWidth(tSepratorWidth);
    pToolBarSpaceSeprator2->setFixedWidth(tSepratorWidth);

    return;
}



// 从日志文件获取当前页数据
void DataAnalyzer::getCurrentPageDataFromLogFile()
{
    // 获取当前周期数据
    QByteArray byte = pLogProcessModule->getCycleData(pCycleAttr->currentCycle);

    // 获取当前页数据
    pDataProcessModule->setCurrentPage(pPageAreaAttr->currentPage);
    pCurrentPageData = pDataProcessModule->decodePageDatas(byte);

    return;
}

void DataAnalyzer::createPageLabel()
{
//    qDebug()<<"start:" <<QDateTime::currentDateTime().toMSecsSinceEpoch();
    if(NULL == pCurrentPageData || NULL == pPageLabelsArray) return;

    QPalette pe;
    pe.setColor(QPalette::WindowText, QColor(*pOptions->pLabelTextColor));

    if(false == pPageLabelsArray->isEmpty())
    {
        clearLabelsArray();
    }

    if(NULL == pCurrentPageData->context) return;


    for (auto &item : std::as_const(*pCurrentPageData->context)) {
        quint8 item_row = *item->row - 1;
        switch (MAP_DISPLAY_TYPE.value(item->displayType->toUpper())) {
            case 0:
            {
                quint8 title_col = (*item->column - 1) << 1;
                pOptions->pFont->setBold(true);
                QList<QLabel*> titleLabels = pLabelsWidgetArray[title_col]->findChildren<QLabel*>();
                QLabel* titleLabel = titleLabels.at(item_row);
                titleLabel->setFont(*pOptions->pFont);
                titleLabel->setPalette(pe);
                titleLabel->setAlignment(Qt::AlignVCenter);
                titleLabel->setFixedWidth(pLabelsWidgetArray[title_col]->width() - (pLabelsWidgetArray[title_col]->layout()->contentsMargins().left() << 1));
                titleLabel->setText(*item->title);
                titleLabel->show();
                if (NULL != item->displayType) {
                    pPageLabelsArray->push_back(titleLabel);
                }

                break;
            }
            default:
            {
                quint8 title_col = (*item->column - 1) << 1;
                QList<QLabel*> titleLabels = pLabelsWidgetArray[title_col]->findChildren<QLabel*>();
                pOptions->pFont->setBold(false);
                QLabel* titleLabel = titleLabels.at(item_row);

                titleLabel->installEventFilter(this);

                titleLabel->setObjectName("title");
                titleLabel->setFont(*pOptions->pFont);
                titleLabel->setPalette(pe);
                titleLabel->setAlignment(Qt::AlignVCenter);
                titleLabel->setFixedWidth(pLabelsWidgetArray[title_col]->width() - (pLabelsWidgetArray[title_col]->layout()->contentsMargins().left() << 1));
                titleLabel->setText(*item->title);
                titleLabel->show();

                quint8 value_col = (*item->column << 1) - 1;
                QList<QLabel*> valueLabels = pLabelsWidgetArray[value_col]->findChildren<QLabel*>();
                QLabel* valueLabel = valueLabels.at(item_row);
                valueLabel->installEventFilter(this);
                valueLabel->setObjectName("value");
                valueLabel->setFont(*pOptions->pFont);
                valueLabel->setPalette(pe);
                valueLabel->setAlignment(Qt::AlignVCenter);
                valueLabel->setFixedWidth(pLabelsWidgetArray[value_col]->width() - (pLabelsWidgetArray[value_col]->layout()->contentsMargins().left() << 1));
                valueLabel->show();
                if (NULL != item->displayType) {
                    pPageLabelsArray->push_back(titleLabel);
                    pPageLabelsArray->push_back(valueLabel);
                }

                break;
            }
        }

    }
//    qDebug()<<"end:" <<QDateTime::currentDateTime().toMSecsSinceEpoch();
    return;
}


// 显示当前页面数据
void DataAnalyzer::showCurrentPage()
{
//    qDebug()<<"start:" <<QDateTime::currentDateTime().toMSecsSinceEpoch();
    if(NULL == pCurrentPageData || NULL == pCurrentPageData->context || pPageLabelsArray->isEmpty()) return;

    quint16 index = 0;

    for (auto &item : std::as_const(*pCurrentPageData->context)) {
        if (NULL == item->displayType) continue;
        switch (MAP_DISPLAY_TYPE.value(item->displayType->toUpper())) {
            case 0:
                ++index;
                break;
            default:
            {
                if (0 != pPageLabelsArray->at(++index)->text().compare(*item->currentCycleValue)) pPageLabelsArray->at(index)->setText(*item->currentCycleValue);
                ++index;
                break;
            }
        }
    }
//    qDebug()<<"end:" <<QDateTime::currentDateTime().toMSecsSinceEpoch();
    pCycleSlider->setFocus();
    return;
}


// 从暂停数据中获取当前页数据
void DataAnalyzer::getCurrentPageDataFromPauseData()
{
    // 获取当前周期数据
    QByteArray byte = pDataProcessModule->getPauseData(pCycleAttr->currentCycle);

    // 获取当前页数据
    pDataProcessModule->setCurrentPage(pPageAreaAttr->currentPage);
    pCurrentPageData = pDataProcessModule->decodePageDatas(byte.toHex().toBase64());

}


// 更新当前页数据
void DataAnalyzer::updateCurrentPageSlot(QString cycleNumber, QString cycleTime, pPAGE_CONTEXT pPageData)
{
    if (!pDrawWidget || !pDataSource) return;
    pDrawWidget->setCurrentCycle(pCycleAttr->currentCycle);

    if(*pDataSource == DATA_SOURCE::LOGFILE)
    {
        if (!pDataProcessModule || !pLogProcessModule) return;
//        createPageLabel();
        pDataProcessModule->decodeToolBarData(pLogProcessModule->getCycleData(pCycleAttr->currentCycle));
        updateToolBar(pDataProcessModule->getCycleNumber(),pDataProcessModule->getCycleTime());
        showCurrentPage();
        setPageButtonsStatus();
        setCycleButtonsStatus();

        updateTextbrowser();
        this->update();
        // pCycleSlider->setFocus();
        return;
    }

    if (pauseFlag)
    {
        if (!pDataProcessModule) return;
        createPageLabel();
        pDataProcessModule->decodeToolBarData(pDataProcessModule->getPauseData(pCycleAttr->currentCycle).toHex().toBase64());
        updateToolBar(pDataProcessModule->getCycleNumber(),pDataProcessModule->getCycleTime());
        showCurrentPage();
        setPageButtonsStatus();
        setCycleButtonsStatus();

        updateTextbrowser();
        this->update();
        // pCycleSlider->setFocus();

        return;
    }

    if ((udpStartFlag || pageChangeFlag) && !pauseFlag) {
        pCurrentPageData = pPageData;
        createPageLabel();
        pageChangeFlag = false;
        udpStartFlag = false;
    }

    switch(*pShowMode) {
    case SHOW_MODE::DIGITAL:
    {
        pCurrentPageData = pPageData;
        showCurrentPage();

        break;
    }

    case SHOW_MODE::IMAGE:
    {
        updateTextbrowser();
        pDrawWidget->setCurrentCycle(pCycleAttr->currentCycle);
        pDrawWidget->update();
        break;
    }
    default:
        break;
    }

    setCycleButtonsStatus();
    updateToolBar(cycleNumber, cycleTime);

    // 如果实时接收，则当前周期号+1
    ++pCycleAttr->currentCycle;

    setPageButtonsStatus();
    return;

}



void DataAnalyzer::cycleChange(int step)
{
    if (pCycleAttr->currentCycle + step <= 1 || pCycleAttr->currentCycle + step >= pCycleAttr->maxCycle) {
        if (pCycleAttr->currentCycle + step <= 1) {
            pCycleAttr->currentCycle = 1;
            pButtonBackward->setDisabled(true);
            pButtonMultipleBackard->setDisabled(true);
        }

        if (pCycleAttr->currentCycle + step >= pCycleAttr->maxCycle) {
            pCycleAttr->currentCycle = pCycleAttr->maxCycle;
            pButtonForward->setDisabled(true);
            pButtonMultipleForward->setDisabled(true);
        }

    } else {

        pCycleAttr->currentCycle += step;
        pButtonForward->setEnabled(true);
        pButtonMultipleForward->setEnabled(true);
        pButtonBackward->setEnabled(true);
        pButtonMultipleBackard->setEnabled(true);
    }

    updateFromLogOrPauseData();


    pCycleSlider->setValue(pCycleAttr->currentCycle);

    return;

}

void DataAnalyzer::pageChange(uint page)
{
    if(page > pPageAreaAttr->maxPage || page < 1 || page == pPageAreaAttr->currentPage)
    {
        return;
    }
    pPageAreaAttr->currentPage = page;
    pageChangeFlag = true;
    pLineEnditPage->setText(QString::number(pPageAreaAttr->currentPage));

    if(*pDataSource == DATA_SOURCE::LOGFILE || pauseFlag)
    {
        updateFromLogOrPauseData();
        createPageLabel();
        updateCurrentPageSlot();
        return;
    }


    pDataProcessModule->setCurrentPage(pPageAreaAttr->currentPage);

    return;
}



// 更新工具栏信息
void DataAnalyzer::updateToolBar(QString cycleNumber, QString cycleTime)
{
    pLabelCycleNumber->clear();
    pLabelCycleNumber->setText(cycleNumber);
    pLabelTimeStamp->clear();
    pLabelTimeStamp->setText(cycleTime);

    return;
}


// 设备选择按钮响应函数
void DataAnalyzer::actionDeviceSelectSlot()
{
    pDeviceProcessModule->readConfig(QApplication::applicationDirPath()+"/Config/Target.xcf");

    if(pDeviceProcessModule->getAllDevices()->count() > 0)
    {
        ui->actionBatchReceive->setEnabled(true);
    }

    ConfigSetting configDialog(pDeviceProcessModule->getAllDevices(), pDeviceProcessModule->getSelectedDevice(), pProtocolProcessModule->getXmlFilePath(), this);

    // 配置对话框确认后的信息接收
    connect(&configDialog, &ConfigSetting::confirm, this, [=](Target device, QString filePath){

        // 设置选择目标设备
        pDeviceProcessModule->setSelectedDevice(device);

        ui->actionBatchReceive->setEnabled(true);

        // 读取配置文件
        if(false == pProtocolProcessModule->readProtocol(filePath))
        {
            ui->actionReceiveMessage->setDisabled(true);
            ui->actionOpenLog->setDisabled(true);
            pProtocolProcessModule->clearXmlFilePath();
            return;
        }

        // 修改窗口标题
        QString windowtitle = mWindowTitle + "_" +
                *pProtocolProcessModule->getFormat_Settings()->Check_Infos->Project + "_" +
                *pProtocolProcessModule->getFormat_Settings()->Check_Infos->Product + "_" +
                *pProtocolProcessModule->getFormat_Settings()->Check_Infos->BaseLine + "_" +
                *pProtocolProcessModule->getFormat_Settings()->Check_Infos->Date + "_" +
                device.getDeviceName();


        this->setWindowTitle(windowtitle);

        ui->actionReceiveMessage->setEnabled(true);
        ui->actionOpenLog->setEnabled(true);
        ui->actionReplay->setDisabled(true);

        // 将曲线添加至曲线添加选择下拉框
        addAllCurvesToComboBoxCurveAdd();

        // 初始化页面数据
        pDataProcessModule->initAllPages(pProtocolProcessModule->getFormat_Settings());

    });

    configDialog.exec();


    connect(pUdpMsgProcessModule, &UdpMsgProcess::receivedData, pDataProcessModule, &DataProcess::msgProcessSlot, Qt::UniqueConnection);

    connect(pDataProcessModule, &DataProcess::pageDataProcessed, this, &DataAnalyzer::updateCurrentPageSlot, Qt::UniqueConnection);

    return;
}


// 配置选项按钮响应函数
void DataAnalyzer::actionOptionsSlot()
{
    connect(pOptionsDialog, &OptionsDialog::confirm, this, [=](){
        // 获取配置选项
        pOptionsDialog->getOptions(pOptions);

        // 重置窗口背景色；
        resetWinddowBackgroundColor();

        // 重置工具栏背景色
        resetToolbarBackgroundColor();

        // 重置绘图区域背景色
        resetImageAreaBackgroundColor();

        // 重置图例背景色
        resetLegendAreaBackgroundColor();
        updateLegendArea();

        // 重置标签字体
        resetLabelFont();

        // 重置标签文字颜色
        resetLabelColor();

        for (auto &item : std::as_const(*pUdpGroup)) {
            item->setRegularSaveTime(*pOptions->pRegularSaveTime);

        }

//        for(QVector<UdpMsgProcess*>::iterator it = pUdpGroup->begin(); it != pUdpGroup->end(); ++it)
//        {
//            (*it)->setRegularSaveTime(*pOptions->pRegularSaveTime);
//        }
    });
    pOptionsDialog->exec();
    return;
}



// 退出按钮响应函数
void DataAnalyzer::actionQuitSlot()
{
    this->close();
    return;
}


// 获取数据按钮响应函数
void DataAnalyzer::actionReceiveMessageSlot()
{   
    if (pauseFlag) {
        pauseFlag = false;
        pDataProcessModule->resume();
        pDrawWidget->setPause(false);
        ui->actionPause->setEnabled(true);
        ui->actionReceiveMessage->setDisabled(true);
        pGroupBoxCycle->hide();
        return;
    }

    resetToolBarGeometry(this->width());
    pUdpMsgProcessModule->setCommonParameters(pCommonParameters);

    // UDP接口模块相关设置
    if (pUdpMsgProcessModule->bind(pDeviceProcessModule->getSelectedDevice()->getLocal(),pDeviceProcessModule->getSelectedDevice()->getRemote()))
    {
        pUdpMsgProcessModule->startReceive();

        ui->actionBatchReceive->setDisabled(true);

        *pDataSource = DATA_SOURCE::UDP;
        pDataProcessModule->clearCurvesList();

        pCycleAttr->currentCycle = 1;

        pUdpMsgProcessModule->setCurrentCycle(pCycleAttr);

        showWidget();

        // 更新工具栏
        pLabelCycleTitle->setText(DISPLAY_CYCLE_TITLE);

        ui->actionPause->setEnabled(true);
        ui->actionStopAndSave->setEnabled(true);

        ui->actionDeviceSelect->setDisabled(true);
        ui->actionReceiveMessage->setDisabled(true);
        ui->actionOpenLog->setDisabled(true);
        ui->actionReplay->setDisabled(true);
        ui->actionStopPlay->setDisabled(true);
        pActionImageDisplay->setEnabled(true);

        pLabelCycleTitle->show();
        pLabelCycleNumber->show();
        pLabelTimeStamp->show();

        ui->actionOpenConfig->setEnabled(true);


    }

    return;

}


// 暂停按钮响应函数
void DataAnalyzer::actionPauseSlot()
{
    pauseFlag = true;
    pDataProcessModule->setPause();
    pDrawWidget->setPause(true);
    showWidget();

    pCycleAttr->maxCycle = pDataProcessModule->getCyclesCount();
    pCycleAttr->currentCycle = pCycleAttr->maxCycle;
    pCycleSlider->setMaximum(pCycleAttr->maxCycle);
    pCycleSlider->setValue(pCycleAttr->maxCycle);
    ui->actionPause->setDisabled(true);
    ui->actionReceiveMessage->setEnabled(true);
    pDrawWidget->setCurrentCycle(pCycleAttr->currentCycle);

}


// 停止并保存按钮响应函数
void DataAnalyzer::actionStopAndSaveSlot()
{
    pUdpMsgProcessModule->stopReceive();

    ui->actionReceiveMessage->setEnabled(true);
    ui->actionOpenLog->setEnabled(true);
    ui->actionDeviceSelect->setEnabled(true);
    ui->actionBatchReceive->setEnabled(true);

    ui->actionPause->setDisabled(true);
    ui->actionStopAndSave->setDisabled(true);
    ui->actionReplay->setDisabled(true);
    ui->actionStopPlay->setDisabled(true);
    pActionDigitalDisplay->setDisabled(true);
    pActionImageDisplay->setDisabled(true);

    pLabelCycleTitle->clear();
    pLabelCycleNumber->clear();
    pLabelTimeStamp->clear();

    hideWidget();
    // 此处添加保存日志功能
    QFileDialog dialog(this,QString("保存日志"));
    dialog.setDirectory(QApplication::applicationDirPath() + "/Log");
    dialog.setNameFilter(QString("data file(*.dat)"));
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    if(dialog.exec() == QFileDialog::Accepted) {
        QStringList filepath = dialog.selectedFiles();
        pDataProcessModule->saveLogToFile(filepath.at(0));
    }

    udpStartFlag = true;
//    *pShowMode = SHOW_MODE::DIGITAL;

    resetValueStatus();
    return;

}


// 打开日志按钮响应函数
void DataAnalyzer::actionOpenLogSlot()
{
//    resetValueStatus();
    pLogProcessModule->setFormatSetting(pProtocolProcessModule->getFormat_Settings());
    resetToolBarGeometry(this->width());
    QFileDialog* openLogDialog = new QFileDialog(this);
    openLogDialog->setStyleSheet(QString(QString("QWidget{background:")) + *pOptions->pWindowBackgroundColor + QString(QString(";}")));
    QString logPath;
    *pDataSource = DATA_SOURCE::LOGFILE;
    pDataProcessModule->clearCurvesList();
    if((logPath = openLogDialog->getOpenFileName(this, QString("打开日志文件"), NULL, QString("data file(*.dat)"))).size())
    {
        // 读取日志文件
        pLogProcessModule->readFile(logPath);

        // 获取当前页数据
        getCurrentPageDataFromLogFile();

        // 获取总周期数
        pCycleAttr->maxCycle = pLogProcessModule->getTotalCycleNumber();

        // 设置周期滑块范围
        pCycleSlider->setMaximum(pCycleAttr->maxCycle);

        // 显示当前页
        createPageLabel();
        updateCurrentPageSlot();

        ui->actionBatchReceive->setDisabled(true);


        showWidget();

        // 更新工具栏
        pLabelCycleTitle->setText(DISPLAY_CYCLE_TITLE);

        ui->actionDeviceSelect->setDisabled(true);
        ui->actionOpenLog->setDisabled(true);
        ui->actionReceiveMessage->setDisabled(true);
        ui->actionPause->setDisabled(true);
        ui->actionStopAndSave->setDisabled(true);
        ui->actionReplay->setDisabled(true);
        pActionDigitalDisplay->setDisabled(true);

        pActionImageDisplay->setEnabled(true);
        ui->actionStopPlay->setEnabled(true);

    }
    delete openLogDialog;
    openLogDialog = NULL;

    ui->actionOpenConfig->setEnabled(true);

    ui->actionLogCapture->setEnabled(true);

    return;
}


// 停止播放按钮响应函数
void DataAnalyzer::actionStopPlaySlot()
{
    ui->actionDeviceSelect->setEnabled(true);
    ui->actionReceiveMessage->setEnabled(true);
    ui->actionOpenLog->setEnabled(true);
    ui->actionReplay->setEnabled(true);
    ui->actionBatchReceive->setEnabled(true);

    ui->actionStopPlay->setDisabled(true);
    pActionImageDisplay->setDisabled(true);
    pActionDigitalDisplay->setDisabled(true);
    hideWidget();

    pLabelCycleTitle->clear();
    pLabelCycleNumber->clear();
    pLabelTimeStamp->clear();
    pDataProcessModule->clearCurvesList();
    pComboBoxCurveDel->clear();

    pPageAreaAttr->currentPage = 1;
    pCycleSlider->setValue(pCycleSlider->minimum());

    ui->actionOpenConfig->setDisabled(true);
    ui->actionLogCapture->setDisabled(true);
    resetValueStatus();

    pLogProcessModule->closeFile();

    return;
}


// 重放按钮响应函数
void DataAnalyzer::actionReplaySlot()
{
//    resetValueStatus();
    ui->actionReplay->setDisabled(true);
    ui->actionStopPlay->setEnabled(true);
    pActionImageDisplay->setEnabled(true);

    ui->actionDeviceSelect->setDisabled(true);
    ui->actionOpenLog->setDisabled(true);
    ui->actionReceiveMessage->setDisabled(true);
    ui->actionOpenConfig->setEnabled(true);
    ui->actionLogCapture->setEnabled(true);
    createPageLabel();
    showWidget();
    updateCurrentPageSlot();
    return;
}


// 数字显示按钮
void DataAnalyzer::actionDigitalDisplaySlot()
{
    *pShowMode = SHOW_MODE::DIGITAL;

    pImageArea->hide();

    pDigitalArea->show();

    showWidget();

    pActionDigitalDisplay->setDisabled(true);
    pActionImageDisplay->setEnabled(true);
    return;
}


// 图形显示按钮
void DataAnalyzer::actionImageDisplaySlot()
{
    *pShowMode = SHOW_MODE::IMAGE;

    pImageArea->show();

    pDigitalArea->hide();

    showWidget();
    pActionImageDisplay->setDisabled(true);
    pActionDigitalDisplay->setEnabled(true);

    updateLegendArea();
    updateTextbrowser();
    return;
}



void DataAnalyzer::actionImportConfigSlog()
{
    // 此处添加打开配置功能
    QFileDialog dialog(this,QString("打开配置"));
    dialog.setNameFilter(QString("cfg file(*.cfg)"));
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
    if(dialog.exec() == QFileDialog::Accepted)
    {
        QStringList filepath = dialog.selectedFiles();
        pCurveConfigProcessModule->getConfig(filepath[0]);
        // 清空pComboBoxCurveDel
        pComboBoxCurveDel->clear();

        pDataProcessModule->clearCurvesList();

        // 设置数据来源
        pDataProcessModule->setDataSource(pDataSource);
        pDrawWidget->setDataSource(*pDataSource);

        for (auto &item : std::as_const(*pCurveConfigProcessModule->getCurves())) {
            PDATA_CONTEXT pCurve = pDataProcessModule->addCurve(item);

            if(*pDataSource == DATA_SOURCE::LOGFILE)
            {
                for(int n = 1; n < pCycleAttr->maxCycle + 1; ++n)
                {
                    QByteArray byte = pLogProcessModule->getCycleData(n);
                    pDataProcessModule->addDataToCurvesList(byte, pCurve);
                }
            }

            // 暂停时绘图
            if (pauseFlag) {
                for(int n = 1; n < pCycleAttr->maxCycle + 1; ++n)
                {
                    QByteArray byte = pDataProcessModule->getPauseData(n);
                    pDataProcessModule->addDataToCurvesList(byte.toHex().toBase64(), pCurve);
                }
            }

            pComboBoxCurveDel->addItem(item);
            pComboBoxCurveDel->setCurrentText(item);

            pDrawWidget->setCurvesList(pDataProcessModule->getCurvesList());

            updateTextbrowser();

        }


        pDrawWidget->update();
        pDrawWidget->setCurrentCycle(pCycleAttr->currentCycle);
        pDrawWidget->setScale(*pScale);

        QList<QLabel*> tmplist = pLabelArea->findChildren<QLabel*>();

        if(tmplist.count() * *pOptions->pLegendLabelHeight > pLabelArea->height())
        {
            pLegendScrollBar->setMaximum((tmplist.count() - pLabelArea->height() / *pOptions->pLegendLabelHeight) * *pOptions->pLegendLabelHeight);
            pLegendScrollBar->setValue(pLegendScrollBar->maximum());
        }

        QList<MyWidget*> pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
        if(pWidgetList.count() * TEXTBROWSER_LABEL_HEIGHT > pTextBrowserDisplayValue->height())
        {
            pTextScrollBar->setMaximum((pWidgetList.count() - pTextBrowserDisplayValue->height() / TEXTBROWSER_LABEL_HEIGHT) * TEXTBROWSER_LABEL_HEIGHT);
            pTextScrollBar->setValue(pTextScrollBar->maximum());
        }


        // 将下拉框最小宽度设置为选择添加下拉框同等宽度
        setComboBoxMinWidth(pComboBoxCurveDel, pComboBoxCurveAdd->view()->width());
        setComboBoxMinWidth(pComboBoxCurveDel, pComboBoxCurveAdd->view()->width());
        updateLegendArea();

    }
    return;

}


void DataAnalyzer::actionExportConfigSlot()
{
    // 此处添加保存配置功能
    QFileDialog dialog(this,QString("保存当前配置"));
    dialog.setNameFilter(QString("cfg file(*.cfg)"));
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    if(dialog.exec() == QFileDialog::Accepted)
    {
        QStringList filepath = dialog.selectedFiles();
        pCurveConfigProcessModule->saveConfig(*pDataProcessModule->getCurvesList(), filepath[0]);
    }
    return;
}


// 批量获取
void DataAnalyzer::actionBatchReceiveSlot()
{
    DialogDeviceSelect dialog(this);

    dialog.setSelections(pDeviceProcessModule->getAllDevices());

    connect(&dialog, &DialogDeviceSelect::selected, this, [=](QVector<Target> devices){
        ui->actionBatchReceive->setDisabled(true);
        ui->actionStopBatchReceive->setEnabled(true);
        ui->actionDeviceSelect->setDisabled(true);
        ui->actionOpenLog->setDisabled(true);
        ui->actionReceiveMessage->setDisabled(true);

        for (auto &item : std::as_const(devices)) {
            UdpMsgProcess* receiver = new UdpMsgProcess;

            receiver->setCommonParameters(pCommonParameters);

            // UDP接口模块相关设置
            receiver->bind(item.getLocal(), item.getRemote());

            receiver->setRegularSaveTime(*pOptions->pRegularSaveTime);

            receiver->regularSave(*pOptions->pDefaultPath + QString("\\") + item.getDeviceName());

            pUdpGroup->append(receiver);

        }

        this->resize(pCommonParameters->DEFAULT_WIDTH, 0);

    });

    dialog.exec();
    return;
}


void DataAnalyzer::actionStopBatchSlot()
{
    for (auto &item : std::as_const(*pUdpGroup)) {
        item->stopReceive();
    }

    pUdpGroup->clear();

    ui->actionDeviceSelect->setEnabled(true);
    if(pProtocolProcessModule->getFormat_Settings())
    {
        ui->actionOpenLog->setEnabled(true);
        ui->actionReceiveMessage->setEnabled(true);
    }
    ui->actionBatchReceive->setEnabled(true);
    ui->actionStopBatchReceive->setDisabled(true);

    this->resize(pCommonParameters->DEFAULT_WIDTH, pCommonParameters->DEFAULT_HEIGHT);
    return;

}



// 日志截取
void DataAnalyzer::actionLogCapture()
{
    LogCaptureDialog logDialog(this);
    logDialog.setStartDateTime(pLogProcessModule->getStartDateTime());
    logDialog.setEndDateTime(pLogProcessModule->getEndDateTime());
    connect(&logDialog, &LogCaptureDialog::logCaptureSignal, pLogProcessModule, &LogProcess::logCaptureSlot);

    logDialog.exec();
    return;

}


// ODMS日志转换
void DataAnalyzer::actionODMSTransfer()
{
    ODMSTransferDialog dialog(this);

    dialog.setLastPath(mODMSLogLastPath);

    dialog.exec();
    mODMSLogLastPath = dialog.getLastPath();
    return;
}


// 设备处理模块初始化
void DataAnalyzer::initDeviceProcessModule()
{
    if(NULL == pDeviceProcessModule)
    {
        pDeviceProcessModule = new DeviceProcess;
    }
    pDeviceProcessModule->readConfig(QApplication::applicationDirPath()+"/Config/Target.xcf");
    if(pDeviceProcessModule->getAllDevices()->count() > 0)
    {
        ui->actionBatchReceive->setEnabled(true);
    }
    return;
}


// 协议处理模块初始化
void DataAnalyzer::initProtocolProcessModule()
{
    if(NULL == pProtocolProcessModule)
    {
        pProtocolProcessModule = new ProtocolProcess;
    }
    connect(pProtocolProcessModule, &ProtocolProcess::throwError, this, [=](QString error){
        QMessageBox::warning(this, "警告", QString("协议格式配置文件") + error);
    });
    return;
}


// UDP接口模块初始化
void DataAnalyzer::initUdpMsgProcessModule()
{
    if(NULL == pUdpMsgProcessModule)
    {
        pUdpMsgProcessModule = new UdpMsgProcess;
    }

    connect(this, &DataAnalyzer::destroyed, [&](){
        pUdpMsgProcessModule->stopReceive();
    });
    return;
}


// 数据处理模块初始化
void DataAnalyzer::initDataProcessModule()
{
    if(NULL == pDataProcessModule)
    {
        pDataProcessModule = new DataProcess;
    }
    return;
}


// 日志处理模块初始化
void DataAnalyzer::initLogProcessModule()
{
    if(NULL == pLogProcessModule)
    {
        pLogProcessModule = new LogProcess;
    }
    return;
}

// 曲线配置处理模块初始化
void DataAnalyzer::initCurveConfigProcessModule()
{
    pCurveConfigProcessModule = new CurveConfigProcess;
    return;
}


void DataAnalyzer::initUDPGroup()
{
    pUdpGroup = new QVector<UdpMsgProcess*>;
}

// 曲线添加按钮响应函数
void DataAnalyzer::curveAddButtonSlot()
{
    QString curveName = pComboBoxCurveAdd->currentText();


    // 如果下拉狂曲线的计数为0则返回
    if(pComboBoxCurveAdd->count() == 0) return;


    // 判断是否已添加该曲线，如果已经在曲线列表中，则不重复添加
    if (pComboBoxCurveDel->findText(curveName) >= 0) return;


    // 根据名称获取曲线相关信息
    PDATA_CONTEXT pCurve = pDataProcessModule->addCurve(curveName);

    // 如果添加的曲线为空，则直接返回
    if(nullptr == pCurve) return;

    // if (STRING_DISPLAY_TYPE_TITLE == *pCurve->displayType) return;

    // 添加该曲线到删除曲线下拉列表中，并将删除曲线下拉列表当前值更新为最新添加的曲线
    pComboBoxCurveDel->addItem(curveName);
    pComboBoxCurveDel->setCurrentText(curveName);

    // 设置数据来源
    pDataProcessModule->setDataSource(pDataSource);
    pDrawWidget->setDataSource(*pDataSource);


    if(*pDataSource == DATA_SOURCE::LOGFILE)
    {
        for(int n = 1; n < pCycleAttr->maxCycle + 1; ++n)
        {
            QByteArray byte = pLogProcessModule->getCycleData(n);
            pDataProcessModule->addDataToCurvesList(byte, pCurve);
        }
    }

    // 暂停时绘图
    if (pauseFlag) {
        for(int n = 1; n < pCycleAttr->maxCycle + 1; ++n)
        {
            QByteArray byte = pDataProcessModule->getPauseData(n);
            pDataProcessModule->addDataToCurvesList(byte.toHex().toBase64(), pCurve);
        }
    }

    pDrawWidget->setCurvesList(pDataProcessModule->getCurvesList());
    pDrawWidget->setScale(*pScale);

    if (0 < pDataProcessModule->getCurvesList()->count()) {
        ui->actionSaveConfig->setEnabled(true);
    }
    updateTextbrowser();
    pDrawWidget->update();


    // 更新图例区域
    QList<QLabel*> tmplist = pLabelArea->findChildren<QLabel*>();

    if(tmplist.count() * *pOptions->pLegendLabelHeight > pLabelArea->height())
    {
        pLegendScrollBar->setMaximum((tmplist.count() - pLabelArea->height() / *pOptions->pLegendLabelHeight) * *pOptions->pLegendLabelHeight);
        pLegendScrollBar->setValue(pLegendScrollBar->maximum());
    }

    QList<MyWidget*> pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
    if(pWidgetList.count() * TEXTBROWSER_LABEL_HEIGHT > pTextBrowserDisplayValue->height())
    {
        pTextScrollBar->setMaximum((pWidgetList.count() - pTextBrowserDisplayValue->height() / TEXTBROWSER_LABEL_HEIGHT) * TEXTBROWSER_LABEL_HEIGHT);
        pTextScrollBar->setValue(pTextScrollBar->maximum());
    }


    // 将下拉框最小宽度设置为选择添加下拉框同等宽度
    setComboBoxMinWidth(pComboBoxCurveDel, pComboBoxCurveAdd->view()->width());

    updateLegendArea();    

    curveDelComboBoxIndexChangedSlot();
//    qDebug()<<QDateTime::currentDateTime().toMSecsSinceEpoch();
    return;
}


// 通过在数字界面双击label添加曲线
void DataAnalyzer::labelMouseDoubleClicked(QLabel* titleLabel)
{
    QString title = titleLabel->text();
    if (title.isEmpty()) return;

    if(pComboBoxCurveAdd->count() == 0) return;

    // 判断是否已添加该曲线
    if (pComboBoxCurveDel->findText(title) >= 0) return;


    // 添加该曲线到删除曲线下拉列表中，并将筛选曲线下拉列表和删除曲线下拉列表当前值更新为最新添加的曲线
    pComboBoxCurveDel->addItem(title);
    pComboBoxCurveDel->setCurrentText(title);
    pComboBoxCurveAdd->setCurrentText(title);


//    pDataProcessModule->initSingleVarData(pComboBoxCurveAdd->currentText());
    // 将曲线添加到绘图曲线列表中
    PDATA_CONTEXT pCurve = pDataProcessModule->addCurve(title);


    // 设置数据来源
    pDataProcessModule->setDataSource(pDataSource);
    pDrawWidget->setDataSource(*pDataSource);


    if(*pDataSource == DATA_SOURCE::LOGFILE)
    {
        for(int n = 1; n < pCycleAttr->maxCycle + 1; ++n)
        {
            QByteArray byte = pLogProcessModule->getCycleData(n);
            pDataProcessModule->addDataToCurvesList(byte, pCurve);
        }
    }

    // 暂停时绘图
    if (pauseFlag) {
        for(int n = 1; n < pCycleAttr->maxCycle + 1; ++n)
        {
            QByteArray byte = pDataProcessModule->getPauseData(n);
            pDataProcessModule->addDataToCurvesList(byte.toHex().toBase64(), pCurve);
        }
    }

    pDrawWidget->setCurvesList(pDataProcessModule->getCurvesList());
    pDrawWidget->setScale(*pScale);

    if (0 < pDataProcessModule->getCurvesList()->count()) {
        ui->actionSaveConfig->setEnabled(true);
    }
    updateTextbrowser();
    pDrawWidget->update();

    QList<QLabel*> tmplist = pLabelArea->findChildren<QLabel*>();

    if(tmplist.count() * *pOptions->pLegendLabelHeight > pLabelArea->height())
    {
        pLegendScrollBar->setMaximum((tmplist.count() - pLabelArea->height() / *pOptions->pLegendLabelHeight) * *pOptions->pLegendLabelHeight);
        pLegendScrollBar->setValue(pLegendScrollBar->maximum());
    }

    QList<MyWidget*> pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
    if(pWidgetList.count() * TEXTBROWSER_LABEL_HEIGHT > pTextBrowserDisplayValue->height())
    {
        pTextScrollBar->setMaximum((pWidgetList.count() - pTextBrowserDisplayValue->height() / TEXTBROWSER_LABEL_HEIGHT) * TEXTBROWSER_LABEL_HEIGHT);
        pTextScrollBar->setValue(pTextScrollBar->maximum());
    }


    // 将下拉框最小宽度设置为选择添加下拉框同等宽度
    setComboBoxMinWidth(pComboBoxCurveDel, pComboBoxCurveAdd->view()->width());

    updateLegendArea();

    curveDelComboBoxIndexChangedSlot();
    return;
}

// 根据日志或者暂停数据更新数据
void DataAnalyzer::updateFromLogOrPauseData()
{
    // 从日志获取数据
    if(*pDataSource == DATA_SOURCE::LOGFILE)
    {
        getCurrentPageDataFromLogFile();
        return;
    }

    // 暂停时的数据更新
    if (pauseFlag) {
        getCurrentPageDataFromPauseData();
        return;
    }
}




bool DataAnalyzer::eventFilter(QObject *obj, QEvent *event)
{
    for(auto &label : std::as_const(*pPageLabelsArray)) {
        if (obj == label) {
            label->setAttribute(Qt::WA_Hover, true);
            // 变量名称标签
            switch (MAP_LABEL_TYPE.value(label->objectName().toUpper())){
            case 0:     // title
                switch (event->type()) {
                    case QEvent::MouseButtonDblClick:
                    {
                        labelMouseDoubleClicked(label);
                        break;
                    }

                    case QEvent::Enter:
                    {
                        label->setStyleSheet("QLabel{color: rgb(255,0,0); font: bold " + QString::number(*pOptions->pFontSize + 5) + "px}");
                        break;
                    }

                    case QEvent::Leave:
                    {
                        label->setStyleSheet(QString("QLabel{color:") + *pOptions->pLabelTextColor + "}");
                        break;
                    }

                    case QEvent::HoverEnter:
                    {
                        label->setToolTip(label->text());
                        break;
                    }

                    default:
                        break;

                }
                break;

            case 1:     // value
                if (QEvent::HoverEnter == event->type()) {
                    label->setToolTip(label->text());
                }
                break;

            default:
                break;
            }
        }
    }

    return QMainWindow::eventFilter(obj, event);
}

// 曲线删除按钮响应函数
void DataAnalyzer::curveDelButtonSlot()
{
    if(pComboBoxCurveDel->count() > 0)
    {
        pDataProcessModule->delCurve(pComboBoxCurveDel->currentText());
        pComboBoxCurveDel->removeItem(pComboBoxCurveDel->currentIndex());
        pDrawWidget->setCurvesList(pDataProcessModule->getCurvesList());
    }

    if (0 == pDataProcessModule->getCurvesList()->count()) {
        ui->actionSaveConfig->setDisabled(true);
    }

    pDrawWidget->update();
    updateLegendArea();
    updateTextbrowser();


    QList<MyWidget*> pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
    if(pWidgetList.count() * TEXTBROWSER_LABEL_HEIGHT <= pTextBrowserDisplayValue->height())
    {
        pTextScrollBar->hide();
    }

    QList<QLabel*> tmplist = pLabelArea->findChildren<QLabel*>();

    if(tmplist.count() * *pOptions->pLegendLabelHeight <= pLabelArea->height())
    {
        pLegendScrollBar->hide();
    }

    if(pComboBoxCurveDel->count() == 0)
    {
        pLineEditMax->clear();
        pLineEditMin->clear();
    }

    return;
}

// 曲线改色按钮响应函数
void DataAnalyzer::curveChangeColorButtonSlot()
{
    QColor* color = NULL;
    color = new QColor(QColorDialog::getColor(Qt::red, this, "曲线颜色选择"));
    if(false == color->isValid())
    {
        delete color;
        color = NULL;
        return;
    }

    if(color->isValid())
    {
        if(pComboBoxCurveDel->count()==0)
        {
            delete color;
            color = NULL;
            return;
        }

        QVector<PDATA_CONTEXT>* tmpList = pDataProcessModule->getCurvesList();

        *tmpList->at(pComboBoxCurveDel->currentIndex())->red = color->red();
        *tmpList->at(pComboBoxCurveDel->currentIndex())->green = color->green();
        *tmpList->at(pComboBoxCurveDel->currentIndex())->blue = color->blue();

        delete color;
        color = NULL;
    }
    updateLegendArea();
    return;
}


// 曲线X轴修改响应函数
void DataAnalyzer::curveXRangeChangedSlot()
{
    switch(pComboBoxXZoom->currentIndex())
    {
    case 0:
        *pScale = 1;
        break;

    case 1:
        *pScale = 2;
        break;

    case 2:
        *pScale = 5;
        break;

    case 3:
        *pScale = 10;
        break;

    case 4:
        *pScale = 20;
        break;

    case 5:
        *pScale = 50;
        break;

    case 6:
        *pScale = 100;
        break;

    default:
        break;
    }

    pRulerWidget->setScale(*pScale);
    pDrawWidget->setScale(*pScale);
    pDrawWidget->update();
    return;

}


// 放大按钮响应函数
void DataAnalyzer::zoominButtonSlot()
{
    if(pComboBoxXZoom->currentIndex() > 0)
    {
        pComboBoxXZoom->setCurrentIndex(pComboBoxXZoom->currentIndex() - 1);
    }
    return;
}


// 缩小按钮响应函数
void DataAnalyzer::zoomoutButtonSlot()
{
    if(pComboBoxXZoom->currentIndex() < pComboBoxXZoom->count() - 1)
    {
        pComboBoxXZoom->setCurrentIndex(pComboBoxXZoom->currentIndex() + 1);
    }
    return;
}


// 取值范围确认按钮响应函数
void DataAnalyzer::rangeChangeButtonSlot()
{
    QVector<PDATA_CONTEXT>* tmpList = pDataProcessModule->getCurvesList();

    *tmpList->at(pComboBoxCurveDel->currentIndex())->min = pLineEditMin->text().toInt();
    *tmpList->at(pComboBoxCurveDel->currentIndex())->max = pLineEditMax->text().toInt();
    pDrawWidget->update();
    return;
}


// 快退按钮响应函数
void DataAnalyzer::multipleBackwardButtonSlot()
{
    cycleChange(-*pOptions->pMultipleCyles);
    return;

}


// 后退按钮响应函数
void DataAnalyzer::backwardButtonSlot()
{
    cycleChange(-1);
    return;

}


// 前进按钮响应函数
void DataAnalyzer::forwardButtonSlot()
{
    cycleChange(1);
    return;
}

// 快进按钮响应函数
void DataAnalyzer::multipleForwardButtonSlot()
{
    cycleChange(*pOptions->pMultipleCyles);

    return;

}


// 周期滑块响应函数
void DataAnalyzer::cycleSliderSlot()
{
    pCycleAttr->currentCycle = pCycleSlider->value();

    updateFromLogOrPauseData();

    updateCurrentPageSlot();


    return;
}



// 首页按钮响应函数
void DataAnalyzer::homepageButtonSlot()
{
    pageChange(1);
    return;
}


// 上翻按钮响应函数
void DataAnalyzer::pageupButtonSlot()
{
    if(pPageAreaAttr->currentPage <= 1)
    {
        homepageButtonSlot();
        return;
    }

    pageChange(pPageAreaAttr->currentPage - 1);
    return;
}


// 输入页码后回车响应函数
void DataAnalyzer::lineeditEnterSlot()
{
    uint page = pLineEnditPage->text().toInt();

    pageChange(page);
    return;

}

// 下翻按钮响应函数
void DataAnalyzer::pagedownButtonSlot()
{
    if(pPageAreaAttr->currentPage >= pPageAreaAttr->maxPage)
    {
        endpageButtonSlot();
        return;
    }

    pageChange(pPageAreaAttr->currentPage + 1);
    return;

}


// 尾页按钮响应函数
void DataAnalyzer::endpageButtonSlot()
{
    pageChange(pPageAreaAttr->maxPage);
    return;

}



// 设置翻页按钮状态
void DataAnalyzer::setPageButtonsStatus()
{
    if(pPageAreaAttr->currentPage == 1 && pPageAreaAttr->maxPage > pPageAreaAttr->currentPage)
    {
        pButtonHomePage->setDisabled(true);
        pButtonPageUp->setDisabled(true);

        pButtonPageDown->setEnabled(true);
        pButtonEndPage->setEnabled(true);
        return;
    }
    if(pPageAreaAttr->currentPage == pPageAreaAttr->maxPage && pPageAreaAttr->maxPage > 1)
    {
        pButtonHomePage->setEnabled(true);
        pButtonPageUp->setEnabled(true);

        pButtonPageDown->setDisabled(true);
        pButtonEndPage->setDisabled(true);
        return;
    }

    if(1 == pPageAreaAttr->maxPage)
    {
        pButtonHomePage->setDisabled(true);
        pButtonPageUp->setDisabled(true);

        pButtonPageDown->setDisabled(true);
        pButtonEndPage->setDisabled(true);
        return;
    }

    pButtonHomePage->setEnabled(true);
    pButtonPageUp->setEnabled(true);
    pButtonPageDown->setEnabled(true);
    pButtonEndPage->setEnabled(true);

    return;
}



// 设置周期按钮状态
void DataAnalyzer::setCycleButtonsStatus()
{
    if(pCycleAttr->currentCycle == 1)
    {
        pButtonMultipleBackard->setDisabled(true);
        pButtonBackward->setDisabled(true);

        pButtonForward->setEnabled(true);
        pButtonMultipleForward->setEnabled(true);
        return;
    }

    if(pCycleAttr->currentCycle == pCycleAttr->maxCycle)
    {
        pButtonMultipleBackard->setEnabled(true);
        pButtonBackward->setEnabled(true);

        pButtonForward->setDisabled(true);
        pButtonMultipleForward->setDisabled(true);
        return;
    }

    pButtonMultipleBackard->setEnabled(true);
    pButtonBackward->setEnabled(true);
    pButtonForward->setEnabled(true);
    pButtonMultipleForward->setEnabled(true);

    return;
}


// 添加曲线至曲线添加选择下拉框
void DataAnalyzer::addAllCurvesToComboBoxCurveAdd()
{
    if(pComboBoxCurveAdd->count() > 0)
    {
        pComboBoxCurveAdd->clear();
    }

    struct _format_settings* pFormat = pProtocolProcessModule->getFormat_Settings();
    int combobox_max_len = 0;

    // 计算下拉框中单字符串的宽度
    QFontMetrics fm(pComboBoxCurveAdd->font());

    for (auto &item : std::as_const(*pFormat->Body->Frame->Field)) {
        if(item->Display)
        {
            if(pCommonParameters->WITHOUT_TITLE)
            {
                if(0 == item->Display->Type->compare(STRING_DISPLAY_TYPE_TITLE))
                {
                    continue;
                }
            }
            pComboBoxCurveAdd->addItem(*item->Label);
            if(*item->Display->Position->Page > pPageAreaAttr->maxPage)
            {
                pPageAreaAttr->maxPage = *item->Display->Position->Page;
            }
        }

        if(fm.boundingRect(*item->Label).width() > combobox_max_len)
        {
            combobox_max_len = fm.boundingRect(*item->Label).width();
        }
    }

    setComboBoxMinWidth(pComboBoxCurveAdd, combobox_max_len * COMBOBOX_WIDTH_MULTIPLE);

    return;
}



// 曲线删除下拉框内容变更响应函数()
void DataAnalyzer::curveDelComboBoxIndexChangedSlot()
{
    if(pComboBoxCurveDel->count()==0) return;

    QVector<PDATA_CONTEXT>* curvelist = pDataProcessModule->getCurvesList();

    for (auto &item : std::as_const(*curvelist)) {
        if(0 == item->title->compare(pComboBoxCurveDel->currentText()))
        {
            if(item->min && item->max)
            {
                pLineEditMin->setText(QString::number(*item->min));
                pLineEditMax->setText(QString::number(*item->max));
            }
            return;
        }

    }

//    for(QVector<PDATA_CONTEXT>::iterator it = curvelist->begin(); it != curvelist->end(); ++it)
//    {
//        if(0 == (*it)->title->compare(pComboBoxCurveDel->currentText()))
//        {
//            if((*it)->min && (*it)->max)
//            {
//                pLineEditMin->setText(QString::number(*(*it)->min));
//                pLineEditMax->setText(QString::number(*(*it)->max));
//            }
//            return;
//        }
//    }

    return;
}


// 设置曲线选择相关下拉框最小宽度
void DataAnalyzer::setComboBoxMinWidth(QComboBox* pComboBox, int width)
{
    pComboBox->view()->setMinimumWidth(width);
    pComboBox->view()->setFixedWidth(width);
    return;
}

// 隐藏控件
void DataAnalyzer::hideWidget()
{
    pDigitalArea->hide();
    pImageArea->hide();
    pLegendArea->hide();

    pWidgetDisplayValue->hide();
    pGroupBoxCurveSelection->hide();
    pGroupBoxXZoom->hide();
    pGroupBoxYZoom->hide();
    pGroupBoxCycle->hide();

    pGroupBoxPage->hide();
    return;
}


// 显示控件
void DataAnalyzer::showWidget()
{
    if(*pDataSource == DATA_SOURCE::LOGFILE || pauseFlag)
    {
        pGroupBoxCycle->show();
    }

    pLabelCycleTitle->setText(QString("周期号:"));

    if(*pShowMode == SHOW_MODE::DIGITAL)
    {
        pDigitalArea->show();
        pLegendArea->hide();
        pGroupBoxPage->show();
        pWidgetDisplayValue->hide();
        pGroupBoxCurveSelection->hide();
        pGroupBoxXZoom->hide();
        pGroupBoxYZoom->hide();
        return;
    }

    pImageArea->show();
    pLegendArea->show();
    pWidgetDisplayValue->show();
    pGroupBoxCurveSelection->show();
    pGroupBoxXZoom->show();
    pGroupBoxYZoom->show();
    pGroupBoxPage->hide();
    return;
}


// 重置变量值
void DataAnalyzer::resetValueStatus()
{
    if (!pPageAreaAttr || !pCycleAttr || !pDataSource || !pShowMode || !pCycleSlider || !pDataProcessModule || !pLineEnditPage) return;

    pPageAreaAttr->currentPage = 1;
    pCycleAttr->currentCycle = 1;
    *pShowMode = SHOW_MODE::DIGITAL;
    *pDataSource = DATA_SOURCE::LOGFILE;
    pDataProcessModule->setCurrentPage(pPageAreaAttr->currentPage);
    pComboBoxCurveDel->clear();
    pComboBoxCurveAdd->setCurrentIndex(0);
    pLineEnditPage->setText(QString::number(pPageAreaAttr->currentPage));
    pDataProcessModule->resume();
    pDrawWidget->setPause(false);
    pauseFlag = false;
    return;
}



void DataAnalyzer::updateTextbrowser()
{
    QVector<PDATA_CONTEXT>* pCurvesList = pDataProcessModule->getCurvesList();

    if(pCurvesList)
    {
        QList<MyWidget*> pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
        int index = 0;

        if(pWidgetList.count() < pCurvesList->count())
        {
            for(int n = 0; n < pCurvesList->count() - pWidgetList.count(); ++n)
            {
                MyWidget* widget = new MyWidget(pTextBrowserDisplayValue);
                widget->move(0, (pCurvesList->count() - 1) * TEXTBROWSER_LABEL_HEIGHT);
                widget->show();
            }
        }

        pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();

        QFont font(*pOptions->pFont);
        // font.setPointSize(*pOptions->pFontSize - 1);

        for (auto &pWidget: pWidgetList) {
            ++index;
            pWidget->setFixedSize(this->width() / CONTROL_AREA_EQUAL_PARTS - 21, TEXTBROWSER_LABEL_HEIGHT);

            if(index > pCurvesList->count())
            {
                delete pWidget;
                continue;
            }

            QList<QLabel*> pLabelList = pWidget->findChildren<QLabel*>();
            for(auto &label : pLabelList)
            {
                label->clear();
                label->setFont(font);
                QPalette pe = label->palette();
                pe.setColor(QPalette::WindowText, Qt::black);
                label->setPalette(pe);

                switch(MAP_LABEL_TYPE.value(label->objectName().toUpper())) {
                case 0:     // title
                    label->setText(*pCurvesList->at(index - 1)->title);
                    break;

                case 1:     // value
                {
                    if(0 == pCurvesList->at(index - 1)->displayType->compare(STRING_DISPLAY_TYPE_TITLE)) continue;

                    switch (*pDataSource) {
                    case DATA_SOURCE::LOGFILE:
                        label->setText(*pCurvesList->at(index - 1)->allCyclesStrValues->at(pCycleAttr->currentCycle - 1));
                        break;

                    case DATA_SOURCE::UDP:
                    {
                        // 暂停时的显示
                        if (pauseFlag) {
                            label->setText(*pCurvesList->at(index - 1)->allCyclesStrValues->at(pCycleAttr->currentCycle - 1));
                            continue;
                        }

                        // 实时接收时的显示
                        if(pCurvesList->at(index - 1)->allCyclesStrValues && pCurvesList->at(index - 1)->allCyclesStrValues->count()>0)
                        {
                            label->setText(*pCurvesList->at(index - 1)->allCyclesStrValues->at(pCurvesList->at(index - 1)->allCyclesStrValues->count() - 1));
                        }
                        break;
                    }

                    default:
                        break;
                    }

                    break;
                }

                default:
                    break;
                }

            }
        }


        pWidgetList = pTextBrowserDisplayValue->findChildren<MyWidget*>();
        if(pWidgetList.count() * TEXTBROWSER_LABEL_HEIGHT > pTextBrowserDisplayValue->height() && !pImageArea->isHidden())
        {
            pTextScrollBar->show();
        }
        if(pWidgetList.count() * TEXTBROWSER_LABEL_HEIGHT <= pTextBrowserDisplayValue->height())
        {
            pTextScrollBar->hide();
        }


    }
    return;
}










